Reviewed the semantic of the handler context.

Adapted existing code to fit the new router design.
This commit is contained in:
Jocelyn Fiat
2012-09-27 15:09:41 +02:00
parent cdb88059bc
commit e01c5bec57
36 changed files with 458 additions and 431 deletions

View File

@@ -2,7 +2,7 @@ class
REST_REQUEST_AGENT_HANDLER
inherit
WSF_AGENT_URI_TEMPLATE_HANDLER
WSF_URI_TEMPLATE_AGENT_HANDLER
create
make

View File

@@ -8,7 +8,7 @@ deferred class
REST_REQUEST_HANDLER
inherit
WSF_URI_TEMPLATE_HANDLER
WSF_URI_TEMPLATE_CONTEXT_HANDLER [WSF_HANDLER_CONTEXT]
WSF_HANDLER_HELPER

View File

@@ -10,6 +10,8 @@ deferred class
inherit
WSF_HANDLER_CONTEXT
WSF_REQUEST_UTILITY
feature -- Accept: Content-Type
accepted_content_type: detachable READABLE_STRING_8
@@ -23,7 +25,7 @@ feature -- Accept: Content-Type
get_accepted_content_type (a_supported_content_types: detachable ARRAY [STRING_8])
do
if internal_accepted_content_type = Void then
internal_accepted_content_type := request_accepted_content_type (a_supported_content_types)
internal_accepted_content_type := request_accepted_content_type (request, a_supported_content_types)
end
end
@@ -73,10 +75,10 @@ feature -- Format
request_accepted_format (a_format_variable_name: detachable READABLE_STRING_8; a_supported_content_types: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8
-- Format id for the request based on {HTTP_FORMAT_CONSTANTS}
do
if a_format_variable_name /= Void and then attached string_item (a_format_variable_name) as ctx_format then
Result := ctx_format.as_string_8
if a_format_variable_name /= Void and then attached {WSF_STRING} request.item (a_format_variable_name) as ctx_format then
Result := ctx_format.value
else
Result := request_format_from_content_type (request_accepted_content_type (a_supported_content_types))
Result := request_format_from_content_type (request_accepted_content_type (request, a_supported_content_types))
end
end

View File

@@ -8,7 +8,7 @@ class
REST_REQUEST_URI_TEMPLATE_HANDLER_CONTEXT
inherit
WSF_URI_TEMPLATE_HANDLER_CONTEXT
WSF_HANDLER_CONTEXT
REST_REQUEST_HANDLER_CONTEXT

View File

@@ -38,7 +38,6 @@ feature {NONE} -- Initialization
l_authentication_filter_hdl: AUTHENTICATION_FILTER
l_user_filter: USER_HANDLER
l_user_handler: WSF_URI_TEMPLATE_HANDLER
-- l_routing_hdl: WSF_URI_TEMPLATE_ROUTING_HANDLER --[WSF_HANDLER [WSF_URI_TEMPLATE_HANDLER_CONTEXT], WSF_URI_TEMPLATE_HANDLER_CONTEXT]
l_routing_filter: WSF_ROUTING_FILTER
do
create l_router.make (1)

View File

@@ -42,9 +42,9 @@ feature {NONE} -- Initialization
feature -- Helper: mapping
map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_AGENT_URI_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS)
map_agent_uri (a_uri: READABLE_STRING_8; a_action: like {WSF_URI_AGENT_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS)
do
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_AGENT_URI_HANDLER}.make (a_action)), rqst_methods)
router.map_with_request_methods (create {WSF_URI_MAPPING}.make (a_uri, create {WSF_URI_AGENT_HANDLER}.make (a_action)), rqst_methods)
end
map_uri_template (a_tpl: READABLE_STRING_8; a_handler: WSF_URI_TEMPLATE_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS)
@@ -52,9 +52,9 @@ feature -- Helper: mapping
router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, a_handler), rqst_methods)
end
map_agent_uri_template_response (a_tpl: READABLE_STRING_8; a_action: like {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS)
map_agent_uri_template_response (a_tpl: READABLE_STRING_8; a_action: like {WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER}.action; rqst_methods: detachable WSF_ROUTER_METHODS)
do
router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, create {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}.make (a_action)), rqst_methods)
router.map_with_request_methods (create {WSF_URI_TEMPLATE_MAPPING}.make (a_tpl, create {WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER}.make (a_action)), rqst_methods)
end
feature -- Execution
@@ -114,7 +114,7 @@ feature -- Execution
res.send (mesg)
end
response_user (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
response_user (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
-- Computed response message.
local
html: WSF_HTML_PAGE_RESPONSE
@@ -122,7 +122,7 @@ feature -- Execution
s: STRING_8
l_username: STRING_32
do
if attached {WSF_STRING} ctx.path_parameter ("user") as u then
if attached {WSF_STRING} req.path_parameter ("user") as u then
l_username := (create {HTML_ENCODER}).general_decoded_string (u.value)
if
attached {WSF_STRING} req.query_parameter ("op") as l_op

View File

@@ -13,16 +13,16 @@ inherit
feature -- Access
response (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
response (req: WSF_REQUEST): WSF_RESPONSE_MESSAGE
local
l_username: READABLE_STRING_32
do
if attached {WSF_STRING} ctx.path_parameter ("user") as u then
if attached {WSF_STRING} req.path_parameter ("user") as u then
l_username := html_decoded_string (u.value)
if req.is_request_method ("GET") then
Result := user_message_get (l_username, ctx, req)
Result := user_message_get (l_username, req)
elseif req.is_request_method ("POST") then
Result := user_message_response_post (l_username, ctx, req)
Result := user_message_response_post (l_username, req)
else
Result := unsupported_method_response (req)
end
@@ -46,7 +46,7 @@ feature -- Access
end
user_message_get (u: READABLE_STRING_32; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
user_message_get (u: READABLE_STRING_32; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
local
s: STRING_8
do
@@ -59,7 +59,7 @@ feature -- Access
Result.set_body (s)
end
user_message_response_post (u: READABLE_STRING_32; ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
user_message_response_post (u: READABLE_STRING_32; req: WSF_REQUEST): WSF_HTML_PAGE_RESPONSE
local
s: STRING_8
do

View File

@@ -91,7 +91,7 @@ feature -- Execution
res.redirect_now_with_content (req.script_url ("/"), uri + ": not found.%NRedirection to " + req.script_url ("/"), "text/html")
end
execute_upload (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
execute_upload (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Upload page is requested, either GET or POST
-- On GET display the web form to upload file, by passing ?nb=5 you can upload 5 images
-- On POST display the uploaded files
@@ -110,14 +110,14 @@ feature -- Execution
page.set_body (l_body)
l_body.append ("<h1>EWF: Upload image file</h1>%N")
l_body.append ("<form action=%""+ req.script_url ("/upload") +"%" method=%"POST%" enctype=%"multipart/form-data%">%N")
if attached ctx.string_query_parameter ("nb") as p_nb and then p_nb.is_integer then
n := p_nb.to_integer
if attached {WSF_STRING} req.query_parameter ("nb") as p_nb and then p_nb.is_integer then
n := p_nb.integer_value
else
n := 1
end
if attached ctx.string_query_parameter ("demo") as p_demo then
if attached {WSF_STRING} req.query_parameter ("demo") as p_demo then
create fn.make_from_string (document_root)
fn.set_file_name (p_demo.string)
fn.set_file_name (p_demo.value)
l_body.append ("File: <input type=%"file%" name=%"uploaded_file[]%" size=%"60%" value=%""+ html_encode (fn.string) +"%"></br>%N")
end

View File

@@ -1,30 +1,29 @@
note
description: "Summary description for {WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER}."
description: "Summary description for {WSF_AGENT_CONTEXT_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER
deferred class
WSF_AGENT_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end]
inherit
WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER
WSF_CONTEXT_HANDLER [C]
create
make
feature -- Change
feature {NONE} -- Initialization
make (a_action: like action)
set_action (a_action: like action)
do
action := a_action
end
action: PROCEDURE [ANY, TUPLE [context: WSF_URI_TEMPLATE_HANDLER_CONTEXT; request: WSF_REQUEST; response: WSF_RESPONSE]]
feature -- Access
action: PROCEDURE [ANY, TUPLE [context: C; request: WSF_REQUEST; response: WSF_RESPONSE]]
feature -- Execution
execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
do
action.call ([ctx, req, res])
end

View File

@@ -0,0 +1,36 @@
note
description: "Summary description for {WSF_CONTEXT_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
WSF_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end]
inherit
WSF_HANDLER
feature -- Execution
execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
deferred
end
feature {WSF_ROUTER} -- Mapping
new_mapping (a_resource: READABLE_STRING_8): WSF_ROUTER_CONTEXT_MAPPING [C]
-- New mapping built with Current as handler
deferred
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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

@@ -8,233 +8,27 @@ note
date: "$Date$"
revision: "$Revision$"
deferred class
class
WSF_HANDLER_CONTEXT
inherit
ANY
create
make
WSF_FORMAT_UTILITY
export
{NONE} all
feature {NONE} -- Initialization
make (req: like request; map: like mapping)
do
request := req
mapping := map
end
DEBUG_OUTPUT
feature -- Access
request: WSF_REQUEST
-- Associated request
path: READABLE_STRING_8
-- Associated path
feature -- Request data
apply (req: WSF_REQUEST)
-- Apply current data to request `req'
--| mainly to fill {WSF_REQUEST}.path_parameters
deferred
end
revert (req: WSF_REQUEST)
-- Revert potential previous `apply' for request `req'
--| mainly to restore previous {WSF_REQUEST}.path_parameters
deferred
end
feature -- Url Query
script_absolute_url (a_path: STRING): STRING
-- Absolute Url for the script if any, extended by `a_path'
do
Result := request.absolute_script_url (a_path)
end
script_url (a_path: STRING): STRING
-- Url relative to script name if any, extended by `a_path'
require
a_path_attached: a_path /= Void
do
Result := request.script_url (a_path)
end
url (args: detachable STRING; abs: BOOLEAN): STRING
-- Associated url based on `path' and `args'
-- if `abs' then return absolute url
local
s,t: detachable STRING
do
s := args
if s /= Void and then s.count > 0 then
create t.make_from_string (path)
if s[1] /= '/' and t[t.count] /= '/' then
t.append_character ('/')
t.append (s)
else
t.append (s)
end
s := t
else
s := path
end
if abs then
Result := script_absolute_url (s)
else
Result := script_url (s)
end
ensure
result_attached: Result /= Void
end
feature -- Query
request_accepted_content_type (a_supported_content_types: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8
-- Accepted content-type for the request, among the supported content types `a_supported_content_types'
local
s: detachable READABLE_STRING_8
i,n: INTEGER
do
if
attached accepted_content_types (request) as l_accept_lst and then
not l_accept_lst.is_empty
then
from
l_accept_lst.start
until
l_accept_lst.after or Result /= Void
loop
s := l_accept_lst.item
if a_supported_content_types /= Void then
from
i := a_supported_content_types.lower
n := a_supported_content_types.upper
until
i > n or Result /= Void
loop
if a_supported_content_types [i].same_string (s) then
Result := s
end
i := i + 1
end
else
Result := s
end
l_accept_lst.forth
end
end
end
feature -- Item
item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Variable value for parameter or variable `a_name'
-- See `{WSF_REQUEST}.item(s)'
deferred
end
feature -- Parameter
string_item (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String value for any variable of parameter `a_name' if relevant.
do
Result := string_from (item (a_name))
end
string_array_item (a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32]
-- Array of string values for query parameter `a_name' if relevant.
do
Result := string_array_for (a_name, agent string_item)
end
feature -- Query parameter
query_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Parameter value for query variable `a_name'
--| i.e after the ? character
do
Result := request.query_parameter (a_name)
end
string_query_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String value for query parameter `a_name' if relevant.
do
Result := string_from (query_parameter (a_name))
end
string_array_query_parameter (a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32]
-- Array of string values for query parameter `a_name' if relevant.
do
Result := string_array_for (a_name, agent string_query_parameter)
end
is_integer_query_parameter (a_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is query parameter related to `a_name' an integer value?
do
Result := attached string_query_parameter (a_name) as s and then s.is_integer
end
integer_query_parameter (a_name: READABLE_STRING_GENERAL): INTEGER
-- Integer value for query parameter `a_name' if relevant.
require
is_integer_query_parameter: is_integer_query_parameter (a_name)
do
Result := integer_from (query_parameter (a_name))
end
feature -- Convertion
string_from (a_value: detachable WSF_VALUE): detachable READABLE_STRING_32
-- String value from `a_value' if relevant.
do
if attached {WSF_STRING} a_value as val then
Result := val.value
end
end
integer_from (a_value: detachable WSF_VALUE): INTEGER
-- String value from `a_value' if relevant.
do
if attached string_from (a_value) as val then
if val.is_integer then
Result := val.to_integer
end
end
end
feature {NONE} -- Implementation
string_array_for (a_name: READABLE_STRING_GENERAL; a_item_fct: FUNCTION [ANY, TUPLE [READABLE_STRING_GENERAL], detachable READABLE_STRING_32]): detachable ARRAY [READABLE_STRING_32]
-- Array of string values for query parameter `a_name' if relevant.
local
i: INTEGER
n: INTEGER
do
from
i := 1
n := 1
create Result.make_filled ("", 1, 5)
until
i = 0
loop
if attached a_item_fct.item ([a_name + "[" + i.out + "]"]) as v then
Result.force (v, n)
n := n + 1
i := i + 1
else
i := 0 -- Exit
end
end
Result.keep_head (n - 1)
end
feature -- Status report
debug_output: STRING
-- String that should be displayed in debugger to represent `Current'.
do
Result := path
end
mapping: WSF_ROUTER_MAPPING
-- Associated mapping
;note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"

View File

@@ -0,0 +1,30 @@
note
description: "Summary description for {WSF_ROUTER_CONTEXT_MAPPING}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
WSF_ROUTER_CONTEXT_MAPPING [C -> WSF_HANDLER_CONTEXT create make end]
inherit
WSF_ROUTER_MAPPING
feature -- Access
handler: WSF_CONTEXT_HANDLER [C]
-- Handler associated with Current mapping.
deferred
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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

@@ -1,137 +0,0 @@
note
description: "[
Context for the handler execution
The associated context {WSF_URI_TEMPLATE_HANDLER_CONTEXT} add information about the matched map
- uri_template : the associated URI_TEMPLATE
- uri_template_match : the matching result providing path variables
- additional path_parameter (..) and related queries
In addition to what WSF_HANDLER_CONTEXT already provides, i.e:
- request: WSF_REQUEST -- Associated request
- path: READABLE_STRING_8 -- Associated path
]"
date: "$Date$"
revision: "$Revision$"
class
WSF_URI_TEMPLATE_HANDLER_CONTEXT
inherit
WSF_HANDLER_CONTEXT
redefine
item
end
WSF_REQUEST_PATH_PARAMETERS_SOURCE
create
make
feature {NONE} -- Initialization
make (req: WSF_REQUEST; tpl: URI_TEMPLATE; tpl_res: URI_TEMPLATE_MATCH_RESULT; p: like path)
do
request := req
uri_template := tpl
uri_template_match := tpl_res
path := p
end
feature -- Access
uri_template: URI_TEMPLATE
uri_template_match: URI_TEMPLATE_MATCH_RESULT
feature -- Environment
path_parameters_count: INTEGER
do
Result := uri_template_match.path_variables.count
end
urlencoded_path_parameters: TABLE_ITERABLE [READABLE_STRING_8, READABLE_STRING_8]
-- <Precursor>
do
Result := uri_template_match.path_variables
end
previous_path_parameters_source: detachable WSF_REQUEST_PATH_PARAMETERS_SOURCE
apply (req: WSF_REQUEST)
-- <Precursor>
do
previous_path_parameters_source := req.path_parameters_source
req.set_path_parameters_source (Current)
end
revert (req: WSF_REQUEST)
-- <Precursor>
do
req.set_path_parameters_source (previous_path_parameters_source)
previous_path_parameters_source := Void
end
feature -- Item
item (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Variable value for parameter or variable `a_name'
-- See `{WSF_REQUEST}.item(s)'
do
Result := path_parameter (a_name) --| Should we handle url-encoded name?
if Result = Void then
Result := request.item (a_name)
end
end
feature -- Path parameter
path_parameter (a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
local
n: READABLE_STRING_8
do
n := uri_template_match.encoded_name (a_name)
if attached uri_template_match.path_variable (n) as s then
create {WSF_STRING} Result.make (n, s)
end
end
is_integer_path_parameter (a_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is path parameter related to `a_name' an integer value?
do
Result := attached string_path_parameter (a_name) as s and then s.is_integer
end
integer_path_parameter (a_name: READABLE_STRING_GENERAL): INTEGER
-- Integer value for path parameter `a_name' if relevant.
require
is_integer_path_parameter: is_integer_path_parameter (a_name)
do
Result := integer_from (path_parameter (a_name))
end
string_path_parameter (a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String value for path parameter `a_name' if relevant.
do
Result := string_from (path_parameter (a_name))
end
string_array_path_parameter (a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32]
-- Array of string values for path parameter `a_name' if relevant.
do
Result := string_array_for (a_name, agent string_path_parameter)
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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

@@ -1,11 +1,11 @@
note
description: "Summary description for {WSF_AGENT_HANDLER}."
description: "Summary description for {WSF_URI_AGENT_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_AGENT_URI_HANDLER
WSF_URI_AGENT_HANDLER
inherit
WSF_URI_HANDLER

View File

@@ -31,7 +31,7 @@ feature -- Mapping helper: uri agent
map_uri_agent_with_request_methods (a_uri: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS)
do
map_uri_with_request_methods (a_uri, create {WSF_AGENT_URI_HANDLER}.make (proc), rqst_methods)
map_uri_with_request_methods (a_uri, create {WSF_URI_AGENT_HANDLER}.make (proc), rqst_methods)
end
note

View File

@@ -1,11 +1,11 @@
note
description: "Summary description for {WSF_AGENT_URI_TEMPLATE_HANDLER}."
description: "Summary description for {WSF_URI_TEMPLATE_AGENT_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_AGENT_URI_TEMPLATE_HANDLER
WSF_URI_TEMPLATE_AGENT_HANDLER
inherit
WSF_URI_TEMPLATE_HANDLER

View File

@@ -1,11 +1,11 @@
note
description: "Summary description for {WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER}."
description: "Summary description for {WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_AGENT_URI_TEMPLATE_RESPONSE_HANDLER
WSF_URI_TEMPLATE_RESPONSE_AGENT_HANDLER
inherit
WSF_URI_TEMPLATE_RESPONSE_HANDLER

View File

@@ -31,7 +31,7 @@ feature -- Mapping helper: uri agent
map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS)
do
map_uri_template_with_request_methods (a_tpl, create {WSF_AGENT_URI_TEMPLATE_HANDLER}.make (proc), rqst_methods)
map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_HANDLER}.make (proc), rqst_methods)
end
note

View File

@@ -0,0 +1,31 @@
note
description: "Summary description for {WSF_URI_TEMPLATE_AGENT_CONTEXT_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_URI_TEMPLATE_AGENT_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end]
inherit
WSF_URI_TEMPLATE_CONTEXT_HANDLER [C]
WSF_AGENT_CONTEXT_HANDLER [C]
rename
set_action as make
end
create
make
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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

@@ -1,37 +1,37 @@
note
description: "Summary description for {WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTED_SERVICE}."
description: "Summary description for {WSF_URI_TEMPLATE_CONTEXT_ROUTED_SERVICE}."
author: ""
date: "$Date$"
revision: "$Revision$"
deferred class
WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTED_SERVICE
WSF_URI_TEMPLATE_CONTEXT_ROUTED_SERVICE [C -> WSF_HANDLER_CONTEXT create make end]
inherit
WSF_ROUTED_SERVICE
feature -- Mapping helper: uri
map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER)
map_uri_template (a_tpl: STRING; h: WSF_URI_TEMPLATE_CONTEXT_HANDLER [C])
do
map_uri_template_with_request_methods (a_tpl, h, Void)
end
map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER; rqst_methods: detachable WSF_ROUTER_METHODS)
map_uri_template_with_request_methods (a_tpl: READABLE_STRING_8; h: WSF_URI_TEMPLATE_CONTEXT_HANDLER [C]; rqst_methods: detachable WSF_ROUTER_METHODS)
do
router.map_with_request_methods (create {WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING}.make (a_tpl, h), rqst_methods)
router.map_with_request_methods (create {WSF_URI_TEMPLATE_CONTEXT_MAPPING [C]}.make (a_tpl, h), rqst_methods)
end
feature -- Mapping helper: uri agent
map_uri_template_agent (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]])
map_uri_template_agent (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]])
do
map_uri_template_agent_with_request_methods (a_tpl, proc, Void)
end
map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS)
map_uri_template_agent_with_request_methods (a_tpl: READABLE_STRING_8; proc: PROCEDURE [ANY, TUPLE [ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE]]; rqst_methods: detachable WSF_ROUTER_METHODS)
do
map_uri_template_with_request_methods (a_tpl, create {WSF_AGENT_URI_TEMPLATE_WITH_CONTEXT_HANDLER}.make (proc), rqst_methods)
map_uri_template_with_request_methods (a_tpl, create {WSF_URI_TEMPLATE_AGENT_CONTEXT_HANDLER [C] }.make (proc), rqst_methods)
end
note

View File

@@ -1,18 +1,18 @@
note
description: "Summary description for {WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTING_HANDLER}."
description: "Summary description for {WSF_URI_TEMPLATE_ROUTING_CONTEXT_HANDLER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_URI_TEMPLATE_WITH_CONTEXT_ROUTING_HANDLER
WSF_URI_TEMPLATE_ROUTING_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end]
inherit
WSF_ROUTING_HANDLER
WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER
WSF_URI_TEMPLATE_CONTEXT_HANDLER [C]
rename
execute as uri_template_xecute
execute as uri_template_execute
end
create
@@ -21,7 +21,9 @@ create
feature -- Execution
uri_template_xecute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
uri_template_execute (ctx: C; req: WSF_REQUEST; res: WSF_RESPONSE)
-- <Precursor>
--| For such routing handler, the previous context is lost
do
execute (req, res)
end

View File

@@ -5,20 +5,14 @@ note
revision: "$Revision$"
deferred class
WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER
WSF_URI_TEMPLATE_CONTEXT_HANDLER [C -> WSF_HANDLER_CONTEXT create make end]
inherit
WSF_HANDLER
feature -- Execution
execute (ctx: WSF_URI_TEMPLATE_HANDLER_CONTEXT; req: WSF_REQUEST; res: WSF_RESPONSE)
deferred
end
WSF_CONTEXT_HANDLER [C]
feature {WSF_ROUTER} -- Mapping
new_mapping (a_tpl: READABLE_STRING_8): WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING
new_mapping (a_tpl: READABLE_STRING_8): WSF_URI_TEMPLATE_CONTEXT_MAPPING [C]
do
create Result.make (a_tpl, Current)
end

View File

@@ -1,14 +1,14 @@
note
description: "Summary description for {EWF_ROUTER_URI_TEMPLATE_WITH_CONTEXT_PATH}."
description: "Summary description for {WSF_URI_TEMPLATE_CONTEXT_MAPPING}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_URI_TEMPLATE_WITH_CONTEXT_MAPPING
WSF_URI_TEMPLATE_CONTEXT_MAPPING [C -> WSF_HANDLER_CONTEXT create make end]
inherit
WSF_ROUTER_MAPPING
WSF_ROUTER_CONTEXT_MAPPING [C]
create
make,
@@ -29,7 +29,7 @@ feature {NONE} -- Initialization
feature -- Access
handler: WSF_URI_TEMPLATE_WITH_CONTEXT_HANDLER
handler: WSF_URI_TEMPLATE_CONTEXT_HANDLER [C]
template: URI_TEMPLATE
@@ -46,26 +46,28 @@ feature -- Status
local
tpl: URI_TEMPLATE
p: READABLE_STRING_32
ctx: detachable WSF_URI_TEMPLATE_HANDLER_CONTEXT
ctx: detachable C
new_src: detachable WSF_REQUEST_PATH_PARAMETERS_PROVIDER
do
p := path_from_request (req)
tpl := based_uri_template (template, a_router)
if attached tpl.match (p) as tpl_res then
Result := handler
create ctx.make (req, tpl, tpl_res, path_from_request (req))
create ctx.make (req, Current)
a_router.execute_before (Current)
--| Applied the context to the request
--| in practice, this will fill the {WSF_REQUEST}.path_parameters
ctx.apply (req)
create new_src.make (tpl_res.path_variables.count, tpl_res.path_variables)
new_src.apply (req)
handler.execute (ctx, req, res)
--| Revert {WSF_REQUEST}.path_parameters_source to former value
--| In case the request object passed by other handler that alters its values.
ctx.revert (req)
new_src.revert (req)
a_router.execute_after (Current)
end
rescue
if ctx /= Void then
ctx.revert (req)
if new_src /= Void then
new_src.revert (req)
end
end

View File

@@ -24,7 +24,7 @@ feature {WSF_ROUTER} -- Mapping
Result /= Void and then Result.handler = Current
end
on_mapped (a_mapping: WSF_ROUTER_MAPPING; a_rqst_methods: detachable WSF_ROUTER_METHODS)
on_mapped (a_mapping: like new_mapping; a_rqst_methods: detachable WSF_ROUTER_METHODS)
-- Callback called when a router map a route to Current handler
do
end

View File

@@ -10,6 +10,7 @@ deferred class
feature -- Initialization
initialize_router
-- Initialize router
do
create_router
setup_router
@@ -17,6 +18,7 @@ feature -- Initialization
create_router
-- Create `router'
--| could be redefine to initialize with proper capacity
do
create router.make (10)
ensure
@@ -33,6 +35,8 @@ feature -- Initialization
feature -- Execution
execute (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Dispatch the request
-- and if you dispatch is found, execute the default procedure `execute_default'
do
if attached router.dispatch_and_return_handler (req, res) as p then
-- executed
@@ -42,12 +46,15 @@ feature -- Execution
end
execute_default (req: WSF_REQUEST; res: WSF_RESPONSE)
-- Default procedure
deferred
end
feature -- Access
router: WSF_ROUTER
-- Router used to dispatch the request according to the WSF_REQUEST object
-- and associated request methods
;note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"

View File

@@ -0,0 +1,112 @@
note
description: "Summary description for {WSF_REQUEST_UTILITY}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_REQUEST_UTILITY
inherit
ANY
WSF_FORMAT_UTILITY
export
{NONE} all
end
WSF_VALUE_UTILITY
feature -- Url Query
script_absolute_url (req: WSF_REQUEST; a_path: STRING): STRING
-- Absolute Url for the script if any, extended by `a_path'
do
Result := req.absolute_script_url (a_path)
end
script_url (req: WSF_REQUEST; a_path: STRING): STRING
-- Url relative to script name if any, extended by `a_path'
require
a_path_attached: a_path /= Void
do
Result := req.script_url (a_path)
end
url (req: WSF_REQUEST; a_path: STRING; args: detachable STRING; abs: BOOLEAN): STRING
-- Associated url based on `path' and `args'
-- if `abs' then return absolute url
local
s,t: detachable STRING
do
s := args
if s /= Void and then s.count > 0 then
create t.make_from_string (a_path)
if s[1] /= '/' and t[t.count] /= '/' then
t.append_character ('/')
t.append (s)
else
t.append (s)
end
s := t
else
s := a_path
end
if abs then
Result := script_absolute_url (req, s)
else
Result := script_url (req, s)
end
ensure
result_attached: Result /= Void
end
feature -- Query
request_accepted_content_type (req: WSF_REQUEST; a_supported_content_types: detachable ARRAY [READABLE_STRING_8]): detachable READABLE_STRING_8
-- Accepted content-type for the request, among the supported content types `a_supported_content_types'
local
s: detachable READABLE_STRING_8
i,n: INTEGER
do
if
attached accepted_content_types (req) as l_accept_lst and then
not l_accept_lst.is_empty
then
from
l_accept_lst.start
until
l_accept_lst.after or Result /= Void
loop
s := l_accept_lst.item
if a_supported_content_types /= Void then
from
i := a_supported_content_types.lower
n := a_supported_content_types.upper
until
i > n or Result /= Void
loop
if a_supported_content_types [i].same_string (s) then
Result := s
end
i := i + 1
end
else
Result := s
end
l_accept_lst.forth
end
end
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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,156 @@
note
description: "Summary description for {WSF_VALUE_UTILITY}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
WSF_VALUE_UTILITY
feature -- Parameter
item (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Variable value for parameter or variable `a_name'
-- See `{WSF_REQUEST}.item(s)'
do
Result := req.item (a_name)
end
string_item (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String value for any variable of parameter `a_name' if relevant.
do
Result := string_from (item (req, a_name))
end
string_array_item (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32]
-- Array of string values for query parameter `a_name' if relevant.
do
Result := string_array_for (req, a_name, agent string_item)
end
feature -- Query parameter
query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
-- Parameter value for query variable `a_name'
--| i.e after the ? character
do
Result := req.query_parameter (a_name)
end
string_query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String value for query parameter `a_name' if relevant.
do
Result := string_from (query_parameter (req, a_name))
end
string_array_query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32]
-- Array of string values for query parameter `a_name' if relevant.
do
Result := string_array_for (req, a_name, agent string_query_parameter)
end
is_integer_query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is query parameter related to `a_name' an integer value?
do
Result := attached string_query_parameter (req, a_name) as s and then s.is_integer
end
integer_query_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): INTEGER
-- Integer value for query parameter `a_name' if relevant.
require
is_integer_query_parameter: is_integer_query_parameter (req, a_name)
do
Result := integer_from (query_parameter (req, a_name))
end
feature -- Path parameter
path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable WSF_VALUE
do
Result := req.path_parameter (a_name)
end
string_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable READABLE_STRING_32
-- String value for path parameter `a_name' if relevant.
do
Result := string_from (path_parameter (req, a_name))
end
string_array_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): detachable ARRAY [READABLE_STRING_32]
-- Array of string values for path parameter `a_name' if relevant.
do
Result := string_array_for (req, a_name, agent string_path_parameter)
end
is_integer_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): BOOLEAN
-- Is path parameter related to `a_name' an integer value?
do
Result := attached string_path_parameter (req, a_name) as s and then s.is_integer
end
integer_path_parameter (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL): INTEGER
-- Integer value for path parameter `a_name' if relevant.
require
is_integer_path_parameter: is_integer_path_parameter (req, a_name)
do
Result := integer_from (path_parameter (req, a_name))
end
feature -- Convertion
string_from (a_value: detachable WSF_VALUE): detachable READABLE_STRING_32
-- String value from `a_value' if relevant.
do
if attached {WSF_STRING} a_value as val then
Result := val.value
end
end
integer_from (a_value: detachable WSF_VALUE): INTEGER
-- String value from `a_value' if relevant.
do
if attached string_from (a_value) as val then
if val.is_integer then
Result := val.to_integer
end
end
end
feature {NONE} -- Implementation
string_array_for (req: WSF_REQUEST; a_name: READABLE_STRING_GENERAL; a_item_fct: FUNCTION [ANY, TUPLE [WSF_REQUEST, READABLE_STRING_GENERAL], detachable READABLE_STRING_32]): detachable ARRAY [READABLE_STRING_32]
-- Array of string values for query parameter `a_name' if relevant.
local
i: INTEGER
n: INTEGER
do
from
i := 1
n := 1
create Result.make_filled ("", 1, 5)
until
i = 0
loop
if attached a_item_fct.item ([req, a_name + "[" + i.out + "]"]) as v then
Result.force (v, n)
n := n + 1
i := i + 1
else
i := 0 -- Exit
end
end
Result.keep_head (n - 1)
end
note
copyright: "2011-2012, Jocelyn Fiat, Javier Velilla, 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