indexing description: "XML file resource structure implementation." date: "$Date$" revision: "$Revision$" class PREFERENCE_STRUCTURE_IMP inherit PREFERENCE_STRUCTURE_I redefine save_resources end XM_CALLBACKS_FILTER_FACTORY export {NONE} all end REFACTORING_HELPER create make_empty, make_with_location feature {PREFERENCE_STRUCTURE} -- Initialization make_empty (a_resources: PREFERENCES) is -- Create resource structure in XML file. File will be created based on name of application. -- For operating systems which support it it will stored in the users home directory. For operating -- systems that do not support home directories it will be stored in the current working directory. local l_loc: STRING l_exec: EXECUTION_ENVIRONMENT l_op: OPERATING_ENVIRONMENT do resources := a_resources create l_exec l_op := l_exec.operating_environment if l_op.home_directory_supported then l_loc := l_exec.home_directory_name else l_loc := l_exec.current_working_directory end l_loc.append_character (l_op.directory_separator) l_loc.append ("stored_preferences.xml") make_with_location (a_resources, l_loc) end make_with_location (a_resources: PREFERENCES; a_location: STRING) is -- Create resource structure in the XML file at location `a_location'. -- If file does not exist create new one. do resources := a_resources create session_values.make (5) create xml_structure.make_with_root_named ("EIFFEL_DOCUMENT", create {XM_NAMESPACE}.make_default) location := a_location extract_preferences_from_file ensure then location_set: location = a_location end feature {PREFERENCE_STRUCTURE} -- Resource Management has_resource (a_name: STRING): BOOLEAN is -- Does the underlying store contain a resource with `a_name'? do Result := session_values.has (a_name) end get_resource_value (a_name: STRING): STRING is -- Retrieve the resource string value from the underlying store. do Result := session_values.item (a_name) end save_resource (a_resource: PREFERENCE) is -- Save `a_resource' to the file on disk. do -- TODO: neilc. How to save only a single resource to the file? save_resources (resources.resources.linear_representation, True) end save_resources (a_resources: ARRAYED_LIST [PREFERENCE]; a_save_modified_values_only: BOOLEAN) is -- Save all resources in `a_resources' to storage device. -- If `a_save_modified_values_only' then only resources whose value is different -- from the default one are saved, otherwise all resources are saved. local l_resource: PREFERENCE l_file: PLAIN_TEXT_FILE pref_string1, pref_string2, pref_string3: STRING do pref_string1 := "%N%T" create l_file.make_open_write (location) if l_file.is_open_write then l_file.put_string ("") from a_resources.start until a_resources.after loop l_resource := a_resources.item if not a_save_modified_values_only or else not l_resource.is_default_value then l_file.put_string (pref_string1) l_file.put_string (l_resource.name) l_file.put_string (pref_string2) l_file.put_string (l_resource.string_value) l_file.put_string (pref_string3) else -- nothing to do to remove them from file. end a_resources.forth end l_file.put_string ("%N") l_file.close else fixme ("Add code to let callers that `resources' could not be saved") end end remove_resource (a_resource: PREFERENCE) is -- Remove `resource' from storage device. do end feature {NONE} -- Implementation xml_structure: XM_DOCUMENT -- XML structure built from parsing of `file'. extract_preferences_from_file is -- Extract from the `file' the saved preference values. require location_not_void: location /= Void local parser: XM_EIFFEL_PARSER l_file: KL_TEXT_INPUT_FILE l_tree_pipe: XM_TREE_CALLBACKS_PIPE l_concat_filter: XM_CONTENT_CONCATENATOR attribute: XM_ATTRIBUTE pref_name, pref_value: STRING node: XM_ELEMENT do create parser.make create l_tree_pipe.make create l_concat_filter.make_null parser.set_callbacks (standard_callbacks_pipe (<>)) create l_file.make (location) l_file.open_read if l_file.is_open_read then parser.parse_from_stream (l_file) l_file.close if not l_tree_pipe.error.has_error then xml_structure := l_tree_pipe.document from xml_structure.root_element.start until xml_structure.root_element.after loop node ?= xml_structure.root_element.item_for_iteration if node /= Void then if node.name.is_equal ("PREFERENCE") then -- Found preference attribute := node.attribute_by_name ("NAME") if attribute /= Void then pref_name := attribute.value attribute := node.attribute_by_name ("VALUE") if attribute /= Void then pref_value := attribute.value end session_values.put (pref_value, pref_name) end end end xml_structure.root_element.forth end else fixme ("Add code to let callers know that XML file was invalid") end else fixme ("Add code to let callers that we could not open resource file") end end invariant has_session_values: session_values /= Void has_structure: xml_structure /= Void end -- class PREFERENCE_STRUCTURE_IMP