note description: "Summary description for {WDOCS_API}." author: "" date: "$Date$" revision: "$Revision$" class WDOCS_API inherit CMS_MODULE_API rename make as make_with_cms_api redefine initialize end WDOCS_HELPER REFACTORING_HELPER SHARED_EXECUTION_ENVIRONMENT create make feature {NONE} -- Initialization make (a_default_version_id: READABLE_STRING_GENERAL; a_api: CMS_API; a_setup: WDOCS_SETUP) require a_default_version_id_valid: not a_default_version_id.is_whitespace do default_version_id := a_default_version_id temp_dir := a_setup.temp_dir documentation_dir := a_setup.documentation_dir settings := a_setup make_with_cms_api (a_api) end initialize -- local ct: CMS_WDOCS_CONTENT_TYPE do Precursor create ct cms_api.add_content_type (ct) end feature -- Access settings: WDOCS_SETUP -- Associated configuration. documentation_dir: PATH default_version_id: READABLE_STRING_GENERAL default_editing_version_id: READABLE_STRING_GENERAL do -- if attached available_versions (False) as lst and then not lst.is_empty then -- Result := lst.first -- else Result := default_version_id -- end end feature -- Query label_of_version (a_version_id: READABLE_STRING_GENERAL): detachable READABLE_STRING_32 -- optional label for `a_version_id`. do Result := available_versions (False).item (a_version_id) if Result = Void and then a_version_id.is_case_insensitive_equal (default_version_id) then Result := "current" end end available_versions (a_check_existence: BOOLEAN): STRING_TABLE [detachable READABLE_STRING_32] -- Available versions. local f: PLAIN_TEXT_FILE utf: UTF_CONVERTER ut: FILE_UTILITIES i: INTEGER p: PATH d: DIRECTORY s,lab,v: detachable STRING_32 do if a_check_existence and then attached internal_available_existing_versions as l_existing_versions then Result := l_existing_versions elseif not a_check_existence and then attached internal_available_versions as l_versions then Result := l_versions else create Result.make_equal_caseless (3) if a_check_existence then internal_available_existing_versions := Result else internal_available_versions := Result end create f.make_with_path (settings.documentation_dir.extended ("versions")) if f.exists and then f.is_access_readable then f.open_read from until f.end_of_file or f.exhausted loop f.read_line_thread_aware s := utf.utf_8_string_8_to_string_32 (f.last_string) i := s.index_of (':', 1) if i > 0 then lab := s.substring (i + 1, s.count) v := s v.keep_head (i - 1) lab.left_adjust lab.right_adjust else v := s lab := Void end v.left_adjust v.right_adjust if not v.is_whitespace and then (not a_check_existence or else ut.directory_path_exists (settings.documentation_dir.extended (v))) then Result.force (lab, v) end end f.close else create d.make_with_path (settings.documentation_dir) if d.exists then across d.entries as ic loop p := ic.item if p.is_current_symbol or p.is_parent_symbol then elseif not p.name.starts_with_general (".") then Result.force (Void, p.name) end end end end if Result.is_empty then Result.force ("current", default_version_id.as_string_32) end end end feature {NONE} -- Query internal_available_versions: detachable like available_versions -- cached version of `available_versions (False)`. internal_available_existing_versions: detachable like available_versions -- cached version of `available_versions (True)`. feature -- Query manager (a_version_id: detachable READABLE_STRING_GENERAL): WDOCS_MANAGER -- Wikidocs manager for version `a_version_id'. local v: READABLE_STRING_GENERAL do if a_version_id /= Void then v := a_version_id else v := default_version_id end if attached internal_managers as tb and then attached tb.item (v) as mng then Result := mng else if a_version_id = Void or else a_version_id.same_string (default_version_id) then create Result.make_default (documentation_wiki_dir (default_version_id), default_version_id, temp_dir) else create Result.make (documentation_wiki_dir (a_version_id), a_version_id, temp_dir) end remember_manager (Result) end end documentation_wiki_dir (a_version_id: READABLE_STRING_GENERAL): PATH require a_version_id_not_blank: not a_version_id.is_whitespace do Result := documentation_dir.extended (a_version_id) end feature {NONE} -- Query: cache remember_manager (mng: like manager) -- Cache in memory wdocs manager `mng'. local tb: like internal_managers do tb := internal_managers if tb = Void then create tb.make (1) internal_managers := tb end tb.force (mng, mng.version_id) end internal_managers: detachable STRING_TABLE [WDOCS_MANAGER] -- wdocs manager cache. feature -- Access: cache system clear_all_caches -- Clear all existing wdocs related caches. local retried: BOOLEAN -- p: PATH -- d: DIRECTORY do if not retried then internal_available_versions := Void internal_available_existing_versions := Void across available_versions (False) as ic loop clear_all_cache_for_version (ic.key) end -- -- FIXME: clear remaining cache data, in case it was not cleared yet. -- p := temp_dir.extended ("cache") -- create d.make_with_path (p) -- if d.exists then -- d.recursive_delete -- end else error_handler.add_custom_error (-1, "Clearing cache failed!", Void) end rescue retried := True retry end clear_all_cache_for_version (a_version_id: READABLE_STRING_GENERAL) -- Clear all existing wdocs related caches. -- if `a_version_id` is set, clear only cache related to that version -- else clear all known version caches. local retried: BOOLEAN p: PATH d: DIRECTORY do if not retried then if attached manager (a_version_id) as mng then -- Clear wiki catalog mng.refresh_data -- Clear cms menu across mng.book_names as ic loop reset_cms_menu_cache_for (mng.version_id, ic.item) end end -- FIXME: clear remaining cache data, in case it was not cleared yet. p := temp_dir.extended ("cache").extended (a_version_id).extended ("xhtml") create d.make_with_path (p) if d.exists then d.recursive_delete end else error_handler.add_custom_error (-1, "Clearing cache failed!", {STRING_32} "Failed to clear cache for version %""+ a_version_id.as_string_32 +"%"!") end rescue retried := True retry end cache_for_wiki_page_xhtml (a_version_id: READABLE_STRING_GENERAL; a_book_name: detachable READABLE_STRING_GENERAL; a_wiki_page: WIKI_BOOK_PAGE): WDOCS_FILE_STRING_8_CACHE local p: PATH d: DIRECTORY do p := temp_dir.extended ("cache").extended (a_version_id).extended ("xhtml") if a_book_name /= Void then if a_book_name.is_empty then p := p.extended ("_none_") else p := p.extended (a_book_name) end end create d.make_with_path (p) if not d.exists then d.recursive_create_dir end p := p.extended (normalized_fs_text (a_wiki_page.key)).appended_with_extension ("xhtml") create Result.make (p) end cache_for_book_cms_menu (a_version_id: READABLE_STRING_GENERAL; a_book_name: detachable READABLE_STRING_GENERAL): WDOCS_CACHE [CMS_MENU] -- Cache for cms menu related to `a_version_id'/`a_book_name' or "all". local d: DIRECTORY p: PATH do p := temp_dir.extended ("cache") create d.make_with_path (p) if not d.exists then d.recursive_create_dir end p := p.extended ("cms_menu__book__") p := p.appended (a_version_id) p := p.appended ("_") if a_book_name /= Void then if a_book_name.is_empty then p := p.appended ("_none_") else p := p.appended (a_book_name) end else p := p.appended ("all") end p := p.appended_with_extension ("cache") create {WDOCS_FILE_OBJECT_CACHE [CMS_MENU]} Result.make (p) end reset_cms_menu_cache_for (a_version_id: READABLE_STRING_GENERAL; a_book_name: detachable READABLE_STRING_GENERAL) -- Reset cache for cms menu related to `a_version_id'/`a_book_name' or "all". do cache_for_book_cms_menu (a_version_id, a_book_name).delete end append_available_versions_menu_to_xhtml (pg: detachable like new_wiki_page; a_version_id: detachable READABLE_STRING_GENERAL; a_response: CMS_RESPONSE; a_output: STRING_8) local s, loc, uri: detachable STRING l_link_title, lab: detachable READABLE_STRING_GENERAL l_curr_version: READABLE_STRING_GENERAL l_version_id: READABLE_STRING_GENERAL i: INTEGER do if attached available_versions (False) as l_versions and then not l_versions.is_empty then loc := a_response.location if loc.starts_with_general ("doc/") then if loc.starts_with_general ("doc/version/") then i := loc.index_of ('/', 13) if i > 0 then l_curr_version := loc.substring (13, i - 1) s := loc.substring (i, loc.count) else l_curr_version := loc.substring (13, loc.count) s := "" end else s := loc.substring (4, loc.count) end elseif loc.same_string_general ("documentation") or loc.same_string_general ("documentation/") then s := "" end if s /= Void then a_output.append ("
") a_output.append (cms_api.translation ("Version", Void)) a_output.append ("
%N") end end end append_versions_to_xhtml (a_version_ids: ITERABLE [READABLE_STRING_GENERAL]; a_response: CMS_RESPONSE; a_show_url: BOOLEAN; a_output: STRING_8; a_css_class: detachable READABLE_STRING_8) local s, loc, uri: detachable STRING l_link_title, lab: detachable READABLE_STRING_GENERAL l_curr_version: READABLE_STRING_GENERAL i: INTEGER do if attached available_versions (False) as l_versions and then not l_versions.is_empty then loc := a_response.location if loc.starts_with_general ("doc/") then if loc.starts_with_general ("doc/version/") then i := loc.index_of ('/', 13) if i > 0 then l_curr_version := loc.substring (13, i - 1) s := loc.substring (i, loc.count) else l_curr_version := loc.substring (13, loc.count) s := "" end else s := loc.substring (4, loc.count) end elseif loc.same_string_general ("documentation") or loc.same_string_general ("documentation/") then s := "" end if s /= Void then if a_css_class /= Void then a_output.append ("