|
using System;
using System.IO;
using System.Text;
using System.Xml;
namespace TenTec.Utils
{
/// <summary>
/// Creates a manual from separate topics.
/// </summary>
/// <remarks>
/// This class manager file writing
/// </remarks>
public class ManagerManual: IDisposable
{
#region Fields
/// <summary>
/// The file stream used to write the manual to a
/// temporary file.
/// </summary>
private FileStream fTempStream;
/// <summary>
/// The writer for fTempStream.
/// </summary>
private TextWriter fTempStreamWriter;
/// <summary>
/// The current context level.
/// </summary>
private int fCurrentLevel = 0;
#endregion
#region The pupblic methods
/// <summary>
/// Creates a new instance of the ManagerManual class.
/// </summary>
public ManagerManual()
{
fTempStream = new FileStream(GetTempFileName(), FileMode.Create, FileAccess.ReadWrite);
fTempStreamWriter = new StreamWriter(fTempStream, Encoding.UTF8);
HtmlWriter.WriteStartDocument(fTempStreamWriter);
}
/// <summary>
/// Starts a new section in the manual.
/// </summary>
public void StartSection(string name)
{
if(name == null)
throw new ArgumentNullException("ManagerManual.StartSection(name)");
if(fTempStream == null)
throw new Exception("ManagerManual.StartSection: The manual manager is disposed.");
fCurrentLevel++;
HtmlWriter.WriteHeading(fTempStreamWriter, name, fCurrentLevel);
}
/// <summary>
/// Ends the current section in the manual.
/// </summary>
public void EndSection()
{
if(fTempStream == null)
throw new Exception("ManagerManual.EndSection: The manual manager is disposed.");
if(fCurrentLevel == 0)
throw new Exception("ManagerManual.EndSection: No section was started.");
fCurrentLevel--;
}
/// <summary>
/// Writes the specified text to the current section.
/// </summary>
/// <param name="basePath">
/// The path used to transform relative paths in XML tags
/// to absolute (for example a path to an image).
/// </param>
/// <param name="outputPath">
/// The folder where the output file will be located. It is
/// used to copy files (for example images) specified in XML
/// tags to.
/// </param>
/// <param name="textNode">
/// This node stotes the text to write. Its name should be 'text'.
/// </param>
public void WriteSectionText(XmlNode textNode, string mediaPath, string outputPath)
{
if(textNode == null)
throw new ArgumentNullException("ManagerManual.WriteSectionText(textNode)");
if(outputPath == null)
throw new ArgumentNullException("ManagerManual.WriteSectionText(imagePath)");
if(fTempStream == null)
throw new Exception("ManagerManual.WriteSectionText: The manual manager is disposed.");
HtmlWriter.WriteText(fTempStreamWriter, textNode, mediaPath, outputPath, fCurrentLevel);
}
/// <summary>
/// Writes the manual in to the specified file and disposes the manager.
/// </summary>
public void Flush(string fileNameWithoutExtension)
{
if(fileNameWithoutExtension == null)
throw new ArgumentNullException("ManagerManual.Flush(fileName)");
if(fTempStream == null)
throw new Exception("ManagerManual.Flush: The manual manager is disposed.");
HtmlWriter.WriteEndDocument(fTempStreamWriter, Path.GetDirectoryName(fileNameWithoutExtension));
fTempStreamWriter.Flush();
try
{
File.Copy(fTempStream.Name, fileNameWithoutExtension + ".html", true);
}
finally
{
Dispose();
}
}
#endregion
#region Private Methods
/// <summary>
/// Gets a name for a temporary file.
/// </summary>
private string GetTempFileName()
{
string myTempPath = Path.GetTempPath();
string myFileNameWithoutExt = "TenTec.Utils.ManagerManual.TempFile";
int myIndex = 0;
string myFileName;
while(File.Exists(myFileName = myFileNameWithoutExt + myIndex + ".tmp"))
{
if(myIndex > 500)
throw new IOException("ManagerManual.GetTempFileName: Manual mananger cannot generate a temporary file name.");
myIndex++;
}
return myFileName;
}
#endregion
#region IDisposable Members
/// <summary>
/// Indicates whether the class is disposed.
/// </summary>
private bool fDisposed;
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(true);
// This object will be cleaned up by the Dispose method.
// Therefore, you should call GC.SupressFinalize to
// take this object off the finalization queue
// and prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
private void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if(!fDisposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if(disposing)
{
// Dispose managed resources.
fTempStreamWriter.Close();
try
{
File.Delete(fTempStream.Name);
}
catch{}
fTempStream = null;
fTempStreamWriter = null;
}
// Call the appropriate methods to clean up
// unmanaged resources here.
// If disposing is false,
// only the following code is executed.
}
fDisposed = true;
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~ManagerManual()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
#endregion
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.