indexing
	cluster: "demangler"
	namespace: "candidate"
	description: "Log actions of a SYNC_DIR."
	original_author: "Justin Finnerty"
	original_date: "July 2005"
	current_date: "$Date: 2005/10/31 07:16:01 $"
	current_author: "$Author: finnerty $"
	revision: "$Revision: 2.3 $"	
	-- $Log: action_log.e,v $
	-- Revision 2.3  2005/10/31 07:16:01  finnerty
	-- Added ability to create symlinks between directories as an alternative to merging. The major changes are in DIRDUP_REPORT with others adding/changing features as required.
	--
	-- Revision 2.2  2005/09/27 06:06:22  finnerty
	-- Implemented the logging features
	--
	-- Revision 2.1  2005/09/02 07:36:18  finnerty
	-- Corrected some off-by-one index problems, now generates XML as desired.
	--
	-- Revision 2.0  2005/08/26 23:09:51  finnerty
	-- == Alpha version ==
	--
	-- Revision 1.1  2005/08/21 11:57:01  finnerty
	-- Alpha 1 version
	--
	--

class ACTION_LOG
	-- Software representation of a local file system tree.

creation {ANY}
	make

feature {ANY}
	-- Status Report
	has_log: BOOLEAN is
			-- Is there a log file open?
		do
			Result := (output /= Void)
		end
	
feature {ANY}
	-- Basic operations
	close is
			-- Stop logging and close file.
		do
			if has_log then
				if not stack.is_empty then
					from
					variant
						stack.count
					until
						stack.is_empty
					loop
						output.put_string (stack.item)
						output.put_new_line
						stack.remove
					end
				end
				if output.is_closable then
					output.close
				end
			end
		end

feature {ANY}
	-- Output
	delete_fso (a_path: STRING) is
			-- Log location of to_delete_base
		do
			if has_log then
				output.put_string ("<delete-base>")
				output.put_string (a_path)
				output.put_string ("</delete-base>")
				output.put_new_line
			end
		end

	directory (a_dir: SYNCHRONISED_DIRECTORY) is
			-- Start logging to a_path.
		do
			if has_log then
				if stack.count > 1 then
					from
					variant
						stack.count
					until
						stack.count = 0
					loop
						output.put_string (stack.item)
						stack.remove
					end
				end
				output.put_string ("<directory")
				if a_dir.is_peer then
					output.put_string (" type=%"peer%"")
				else
					output.put_string (" type=%"store%"")
				end
				output.put_string (">")
				output.put_new_line
				root_fso (a_dir.root.name)
				delete_fso (a_dir.to_delete_base.name)
				stack.force ("</directory>")
			end
		end

	move_to (a_old_path, a_new_path: STRING) is
			-- Log action of move_to
		do
			if has_log then
				output.put_string ("<move><from>")
				output.put_string (a_old_path)
				output.put_string ("</from><to>")
				output.put_string (a_new_path)
				output.put_string ("</to></move>")
				output.put_new_line
			end
		end

	rename_to (a_parent_path, a_name, an_new_name: STRING)is
			-- Log action of rename_to
		do
			if has_log then
				output.put_string ("<rename><path>")
				output.put_string (a_parent_path)
				output.put_string ("</path><from>")
				output.put_string (a_name)
				output.put_string ("</from><to>")
				output.put_string (an_new_name)
				output.put_string ("</to></rename>")
				output.put_new_line
			 end
		end

	symlink_to (a_from_path, a_to_name: STRING)is
			-- Log action of symlink_to
		do
			if has_log then
				output.put_string ("<link symbolic=%"True%"><path>")
				output.put_string (a_from_path)
				output.put_string ("</path><target>")
				output.put_string (a_to_name)
				output.put_string ("</target></link>")
				output.put_new_line
			 end
		end

	unlink_to (a_from_path, a_to_name: STRING)is
			-- Log action of unlink_to
		do
			if has_log then
				output.put_string ("<unlink><path>")
				output.put_string (a_from_path)
				output.put_string ("</path><target>")
				output.put_string (a_to_name)
				output.put_string ("</target></unlink>")
				output.put_new_line
			 end
		end

	report (a_report: SYNC_REPORT) is
			-- Add a new report to log
		do
			if has_log then
				if stack.count > 1 then
					from
					variant
						stack.count
					until
						stack.count = 1
					loop
						output.put_string (stack.item)
						output.put_new_line
						stack.remove
					end
				end
				output.put_string ("<report name=%"")
				output.put_string (a_report.generating_type)
				output.put_string ("%"")
				if a_report.is_peer_only then
					output.put_string (" type=%"peer%"")
				elseif a_report.is_store_only then
					output.put_string (" type=%"store%"")
				end
				output.put_string (">")
				output.put_new_line
				stack.force ("</report>")
			end
		end

	root_fso (a_path: STRING) is
			-- Log location of root
		do
			if has_log then
				output.put_string ("<root>")
				output.put_string (a_path)
				output.put_string ("</root>")
				output.put_new_line
			end
		end

feature {NONE}
	-- Create log
	make (a_path: STRING) is
			-- Create a log file with the given name.
		local
			l_out: KL_TEXT_OUTPUT_FILE
		do
			!!l_out.make (a_path)
			l_out.open_write
			if not l_out.is_closed then
				output := l_out
				!DS_LINKED_STACK[STRING]!stack.make_default
				output.put_string ("<?xml version=%"1.0%" encoding=%"UTF-8%"?>")
				output.put_new_line
			end
		end
	
feature {NONE}
	-- Internal attributes
	output: KI_TEXT_OUTPUT_FILE
			-- Stream for output

	stack: DS_STACK[STRING]
			-- Current stack of un finished elements

invariant
	has_log implies output /= Void
	has_log implies stack /= Void
end -- class ACTION_LOG
