diff --git a/library/server/wsf/router/documentation/wsf_router_self_documentation_handler.e b/library/server/wsf/router/documentation/wsf_router_self_documentation_handler.e new file mode 100644 index 00000000..3d9c844f --- /dev/null +++ b/library/server/wsf/router/documentation/wsf_router_self_documentation_handler.e @@ -0,0 +1,58 @@ +note + description: "[ + Handler based on a STARTS_WITH handler to respond a + WSF_ROUTER_SELF_DOCUMENTATION_MESSAGE message + + This is a self documentation for WSF_ROUTER. + ]" + date: "$Date$" + revision: "$Revision$" + +class + WSF_ROUTER_SELF_DOCUMENTATION_HANDLER + +inherit + WSF_STARTS_WITH_HANDLER + redefine + on_mapped + end + +create + make + +feature {NONE} -- Initialization + + make (a_router: WSF_ROUTER) + do + router := a_router + end + + router: WSF_ROUTER + + resource: detachable STRING + +feature {WSF_ROUTER} -- Mapping + + on_mapped (a_mapping: WSF_ROUTER_MAPPING; a_rqst_methods: detachable WSF_ROUTER_METHODS) + -- Callback called when a router map a route to Current handler + do + if attached {WSF_STARTS_WITH_MAPPING} a_mapping as m then + resource := m.uri + end + end + +feature -- Execution + + execute (a_start_path: READABLE_STRING_8; req: WSF_REQUEST; res: WSF_RESPONSE) + local + m: WSF_ROUTER_SELF_DOCUMENTATION_MESSAGE + do + if attached resource as l_resource then + create m.make (req, router, l_resource) + else + create m.make (req, router, Void) + end + res.send (m) + end + +end diff --git a/library/server/wsf/router/documentation/wsf_router_self_documentation_message.e b/library/server/wsf/router/documentation/wsf_router_self_documentation_message.e new file mode 100644 index 00000000..d583dd6e --- /dev/null +++ b/library/server/wsf/router/documentation/wsf_router_self_documentation_message.e @@ -0,0 +1,216 @@ +note + description: "[ + Response message to send a self documentation of the WSF_ROUTER + This is using in addition WSF_SELF_DOCUMENTED_ROUTER_MAPPING and WSF_SELF_DOCUMENTED_HANDLER + ]" + date: "$Date$" + revision: "$Revision$" + +class + WSF_ROUTER_SELF_DOCUMENTATION_MESSAGE + +inherit + WSF_RESPONSE_MESSAGE + +create + make + +feature {NONE} -- Initialization + + make (req: WSF_REQUEST; a_router: WSF_ROUTER; a_resource: detachable STRING) + local + + do + request := req + router := a_router + if attached a_router.base_url as l_base_url then + resource := l_base_url.twin + else + create resource.make_empty + end + if a_resource /= Void then + resource.append (a_resource) + end + end + + request: WSF_REQUEST + + router: WSF_ROUTER + + resource: STRING_8 + +feature {WSF_RESPONSE} -- Output + + send_to (res: WSF_RESPONSE) + -- Send Current message to `res' + -- + -- This feature should be called via `{WSF_RESPONSE}.send (obj)' + -- where `obj' is the current object + local + h: HTTP_HEADER + l_description: STRING_8 + l_base_url: STRING_8 + l_api_resource: detachable STRING_8 + do + create h.make + h.put_content_type_text_html + create l_description.make (1024) + l_description.append ("") + l_description.append ("") + l_description.append ("Documentation") + l_description.append ("[ + + ]") + + l_description.append ("") + + l_description.append ("

Documentation

%N") + + if attached router.base_url as u then + l_base_url := u + else + create l_base_url.make_empty + end + + debug + l_description.append ("

Meta

") + end + + if attached request.path_info as l_path then + if l_path.starts_with (resource) then + l_api_resource := l_path.substring (resource.count + 1, l_path.count) + if l_api_resource.is_empty then + l_api_resource := Void + end + end + end + + if l_api_resource /= Void then + l_description.append ("Index
") + if attached router.item_associated_with_resource (l_api_resource, Void) as l_api_item then + l_description.append ("

Information related to %"" + l_api_resource + "%"

") + end + else + l_description.append ("

Router

") + end + + + l_description.append ("
-- Self generated documentation --
%N") + l_description.append ("") + + h.put_content_length (l_description.count) + h.put_current_date + res.set_status_code ({HTTP_STATUS_CODE}.ok) + res.put_header_text (h.string) + res.put_string (l_description) + end + + append_documentation_to (s: STRING_8; m: WSF_ROUTER_MAPPING; meths: detachable WSF_ROUTER_METHODS) + local + l_url: detachable STRING_8 + l_base_url: detachable READABLE_STRING_8 + hdl: WSF_HANDLER + do + l_base_url := router.base_url + if l_base_url = Void then + l_base_url := "" + end + + l_url := Void + s.append ("
  • ") + s.append ("") + s.append ("") + s.append (m.associated_resource) + s.append ("") + + if attached {WSF_SELF_DOCUMENTED_ROUTER_MAPPING} m as l_doc_mapping then + s.append (" " + html_encoder.encoded_string (l_doc_mapping.documentation) + " ") + else + debug + s.append (" " + m.generating_type.out + " ") + end + end + if meths /= Void then + s.append (" [ ") + across + meths as rq + loop + if l_url /= Void and then rq.item.is_case_insensitive_equal ("GET") then + s.append ("" + rq.item + "") + else + s.append (rq.item) + end + if not rq.is_last then + s.append (",") + end + s.append (" ") + end + s.append ("]") + end + + hdl := m.handler + if attached {WSF_SELF_DOCUMENTED_HANDLER} hdl as l_doc_handler and then attached l_doc_handler.documentation as l_doc then + s.append ("%N%N") + else + debug + s.append ("%N%N") + end + end + if attached {WSF_ROUTING_HANDLER} hdl as l_routing_hdl then + s.append ("%N%N") + end + s.append ("
  • %N") + end + +feature {NONE} -- Implementation + + doc_url (a_api: STRING_8): STRING_8 + do + Result := request.script_url (resource + url_encoder.encoded_string (a_api)) + end + + html_encoder: HTML_ENCODER + once + create Result + end + + url_encoder: URL_ENCODER + once + create Result + end + +end diff --git a/library/server/wsf/router/documentation/wsf_self_documented_handler.e b/library/server/wsf/router/documentation/wsf_self_documented_handler.e new file mode 100644 index 00000000..666b2454 --- /dev/null +++ b/library/server/wsf/router/documentation/wsf_self_documented_handler.e @@ -0,0 +1,16 @@ +note + description: "Summary description for {WSF_SELF_DOCUMENTED_HANDLER}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_SELF_DOCUMENTED_HANDLER + +feature -- Documentation + + documentation: detachable READABLE_STRING_32 + deferred + end + +end diff --git a/library/server/wsf/router/documentation/wsf_self_documented_router_mapping.e b/library/server/wsf/router/documentation/wsf_self_documented_router_mapping.e new file mode 100644 index 00000000..daafb07d --- /dev/null +++ b/library/server/wsf/router/documentation/wsf_self_documented_router_mapping.e @@ -0,0 +1,16 @@ +note + description: "Summary description for {WSF_SELF_DOCUMENTED_ROUTER_MAPPING}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_SELF_DOCUMENTED_ROUTER_MAPPING + +feature -- Documentation + + documentation: READABLE_STRING_32 + deferred + end + +end diff --git a/library/server/wsf/router/support/starts_with/wsf_starts_with_mapping.e b/library/server/wsf/router/support/starts_with/wsf_starts_with_mapping.e index 133da322..35eec54b 100644 --- a/library/server/wsf/router/support/starts_with/wsf_starts_with_mapping.e +++ b/library/server/wsf/router/support/starts_with/wsf_starts_with_mapping.e @@ -23,10 +23,20 @@ feature {NONE} -- Initialization feature -- Access + associated_resource: READABLE_STRING_8 + -- Associated resource + do + Result := uri + end + handler: WSF_STARTS_WITH_HANDLER uri: READABLE_STRING_8 +feature -- Documentation + + documentation: STRING_32 = "Starts-With-URI" + feature -- Status routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER diff --git a/library/server/wsf/router/support/uri/wsf_uri_mapping.e b/library/server/wsf/router/support/uri/wsf_uri_mapping.e index e7dd6a70..4bd74ce1 100644 --- a/library/server/wsf/router/support/uri/wsf_uri_mapping.e +++ b/library/server/wsf/router/support/uri/wsf_uri_mapping.e @@ -10,6 +10,8 @@ class inherit WSF_ROUTER_MAPPING + WSF_SELF_DOCUMENTED_ROUTER_MAPPING + create make, make_trailing_slash_ignored @@ -30,12 +32,22 @@ feature {NONE} -- Initialization feature -- Access + associated_resource: READABLE_STRING_8 + -- Associated resource + do + Result := uri + end + handler: WSF_URI_HANDLER uri: READABLE_STRING_8 trailing_slash_ignored: BOOLEAN +feature -- Documentation + + documentation: STRING_32 = "Is-URI" + feature -- Status routed_handler (req: WSF_REQUEST; res: WSF_RESPONSE; a_router: WSF_ROUTER): detachable WSF_HANDLER diff --git a/library/server/wsf/router/support/uri_template/wsf_uri_template_mapping.e b/library/server/wsf/router/support/uri_template/wsf_uri_template_mapping.e index 2f222cd4..a8cee792 100644 --- a/library/server/wsf/router/support/uri_template/wsf_uri_template_mapping.e +++ b/library/server/wsf/router/support/uri_template/wsf_uri_template_mapping.e @@ -10,6 +10,10 @@ class inherit WSF_ROUTER_MAPPING + WSF_SELF_DOCUMENTED_ROUTER_MAPPING + + DEBUG_OUTPUT + create make, make_from_template @@ -29,10 +33,28 @@ feature {NONE} -- Initialization feature -- Access + associated_resource: READABLE_STRING_8 + -- Associated resource + do + Result := template.template + end + handler: WSF_URI_TEMPLATE_HANDLER template: URI_TEMPLATE +feature -- Documentation + + documentation: STRING_32 = "Match-URI-Template" + +feature -- Status report + + debug_output: STRING + -- String that should be displayed in debugger to represent `Current'. + do + Result := "URI-template: " + template.template + end + feature -- Element change set_handler (h: like handler) diff --git a/library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_mapping.e b/library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_mapping.e index fff3b931..9f76d416 100644 --- a/library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_mapping.e +++ b/library/server/wsf/router/support/uri_template_with_context/wsf_uri_template_context_mapping.e @@ -10,6 +10,8 @@ class inherit WSF_ROUTER_CONTEXT_MAPPING [C] + WSF_SELF_DOCUMENTED_ROUTER_MAPPING + DEBUG_OUTPUT create @@ -31,10 +33,20 @@ feature {NONE} -- Initialization feature -- Access + associated_resource: READABLE_STRING_8 + -- Associated resource + do + Result := template.template + end + handler: WSF_URI_TEMPLATE_CONTEXT_HANDLER [C] template: URI_TEMPLATE +feature -- Documentation + + documentation: STRING_32 = "Is-URI" + feature -- Status report debug_output: STRING diff --git a/library/server/wsf/router/wsf_router.e b/library/server/wsf/router/wsf_router.e index fdfa0f22..dda16aa0 100644 --- a/library/server/wsf/router/wsf_router.e +++ b/library/server/wsf/router/wsf_router.e @@ -114,6 +114,64 @@ feature -- Access end end +feature -- Status report + + has_item_associated_with_resource (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS): BOOLEAN + local + m: WSF_ROUTER_MAPPING + ok: BOOLEAN + do + across + mappings as c + loop + m := c.item.mapping + ok := True + if rqst_methods /= Void then + if attached c.item.request_methods as l_item_rqst_methods then + ok := across rqst_methods as mtd some is_matching_request_methods (mtd.item, l_item_rqst_methods) end + else + ok := True + end + end + if ok then + if attached {WSF_ROUTING_HANDLER} m.handler as l_routing then + Result := l_routing.router.has_item_associated_with_resource (a_resource, rqst_methods) + elseif m.associated_resource.same_string (a_resource) then + Result := True + end + end + end + end + + item_associated_with_resource (a_resource: READABLE_STRING_8; rqst_methods: detachable WSF_ROUTER_METHODS): detachable WSF_ROUTER_ITEM + local + m: WSF_ROUTER_MAPPING + ok: BOOLEAN + do + across + mappings as c + until + Result /= Void + loop + m := c.item.mapping + ok := True + if rqst_methods /= Void then + if attached c.item.request_methods as l_item_rqst_methods then + ok := across rqst_methods as mtd some is_matching_request_methods (mtd.item, l_item_rqst_methods) end + else + ok := True + end + end + if ok then + if attached {WSF_ROUTING_HANDLER} m.handler as l_routing then + Result := l_routing.router.item_associated_with_resource (a_resource, rqst_methods) + elseif m.associated_resource.same_string (a_resource) then + Result := c.item + end + end + end + end + feature -- Hook execute_before (a_mapping: WSF_ROUTER_MAPPING) diff --git a/library/server/wsf/router/wsf_router_mapping.e b/library/server/wsf/router/wsf_router_mapping.e index 81884134..b8c8243b 100644 --- a/library/server/wsf/router/wsf_router_mapping.e +++ b/library/server/wsf/router/wsf_router_mapping.e @@ -13,7 +13,12 @@ feature {NONE} -- Initialization deferred end -feature -- Access +feature -- Access + + associated_resource: READABLE_STRING_8 + -- Associated resource + deferred + end handler: WSF_HANDLER -- Handler associated with Current mapping.