indexing
description: "XML file preference storage implementation."
legal: "See notice at end of class."
status: "See notice at end of class."
date: "$Date$"
revision: "$Revision$"
class
PREFERENCES_STORAGE_XML
inherit
PREFERENCES_STORAGE_I
redefine
initialize_with_preferences,
save_preferences
end
XM_CALLBACKS_FILTER_FACTORY
export
{NONE} all
end
REFACTORING_HELPER
create
make_empty,
make_with_location
feature {NONE} -- Initialization
make_empty is
-- Create preferences storage 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
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 (l_loc)
end
make_with_location (a_location: STRING) is
-- Create preference storage in the XML file at location `a_location'.
-- If file does not exist create new one.
do
create session_values.make (5)
create xml_structure.make_with_root_named ("EIFFEL_DOCUMENT", create {XM_NAMESPACE}.make_default)
location := a_location
ensure then
location_set: location = a_location
end
feature {PREFERENCES} -- Initialization
initialize_with_preferences (a_preferences: PREFERENCES) is
do
Precursor (a_preferences)
extract_preferences_from_file
end
feature {PREFERENCES} -- Resource Management
has_preference (a_name: STRING): BOOLEAN is
-- Does the underlying store contain a preference with `a_name'?
do
Result := session_values.has (a_name)
end
get_preference_value (a_name: STRING): STRING is
-- Retrieve the preference string value from the underlying store.
do
Result := session_values.item (a_name)
end
save_preference (a_preference: PREFERENCE) is
-- Save `a_preference' to the file on disk.
do
-- TODO: neilc. How to save only a single preference to the file?
save_preferences (preferences.preferences.linear_representation, True)
end
save_preferences (a_preferences: ARRAYED_LIST [PREFERENCE]; a_save_modified_values_only: BOOLEAN) is
-- Save all preferences in `a_preferences' to storage device.
-- If `a_save_modified_values_only' then only preferences whose value is different
-- from the default one are saved, otherwise all preferences are saved.
local
l_preference: 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_preferences.start
until
a_preferences.after
loop
l_preference := a_preferences.item
if not a_save_modified_values_only or else not l_preference.is_default_value then
l_file.put_string (pref_string1)
l_file.put_string (l_preference.name)
l_file.put_string (pref_string2)
l_file.put_string (l_preference.string_value)
l_file.put_string (pref_string3)
else
-- nothing to do to remove them from file.
end
a_preferences.forth
end
l_file.put_string ("%N")
l_file.close
else
fixme ("Add code to let callers that `preferences' could not be saved")
end
end
remove_preference (a_preference: PREFERENCE) is
-- Remove `preference' 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
l_attrib: 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
l_attrib := node.attribute_by_name ("NAME")
if l_attrib /= Void then
pref_name := l_attrib.value
l_attrib := node.attribute_by_name ("VALUE")
if l_attrib /= Void then
pref_value := l_attrib.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 preference file")
end
end
invariant
has_session_values: session_values /= Void
has_xml_structure: xml_structure /= Void
indexing
copyright: "Copyright (c) 1984-2006, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
356 Storke Road, Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end