#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

270 lines
8.2 KiB

// <file>
// <copyright see="prj:///Doc/copyright.txt"/>
// <license see="prj:///Doc/license.txt"/>
// <owner name="Christian Hornung" email="c-hornung@gmx.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Resources;
using ICSharpCode.Core;
namespace Hornung.ResourceToolkit.ResourceFileContent
{
/// <summary>
/// Describes the content of a .resources resource file.
/// </summary>
public class ResourcesResourceFileContent : IResourceFileContent
{
readonly string fileName;
readonly CultureInfo culture;
DateTime lastWriteTimeUtc;
Dictionary<string, object> data;
/// <summary>
/// Gets the file name of the resource file this instance represents.
/// </summary>
public string FileName {
get {
return this.fileName;
}
}
/// <summary>
/// Gets the culture of the resource file this instance represents.
/// </summary>
public CultureInfo Culture {
get {
return this.culture;
}
}
/// <summary>
/// Initializes a new instance of the <see cref="ResourcesFileContent" /> class.
/// </summary>
/// <param name="fileName">The file name of the resource file this instance represents.</param>
public ResourcesResourceFileContent(string fileName)
{
this.fileName = fileName;
// Determine culture from file name
string cultureExt = Path.GetExtension(Path.GetFileNameWithoutExtension(fileName));
if (!String.IsNullOrEmpty(cultureExt)) {
try {
this.culture = CultureInfo.GetCultureInfo(cultureExt.Substring(1)); // need to remove leading dot from cultureExt
} catch (ArgumentException) {
this.culture = CultureInfo.InvariantCulture;
}
} else {
this.culture = CultureInfo.InvariantCulture;
}
#if DEBUG
LoggingService.Debug("ResourceToolkit: Created ResourceFileContent, file '"+fileName+"', culture name: '"+this.Culture.Name+"'");
#endif
}
/// <summary>
/// Synchronises the cache with the content of the actual file on disk.
/// </summary>
protected void EnsureLoaded()
{
if (this.data == null || File.GetLastWriteTimeUtc(this.FileName) != this.lastWriteTimeUtc) {
this.InitializeContent();
this.LoadContent();
this.lastWriteTimeUtc = File.GetLastWriteTimeUtc(this.FileName);
}
}
// ********************************************************************************************************************************
/// <summary>
/// Initializes all instance fields in preparation for loading of the file content.
/// </summary>
protected virtual void InitializeContent()
{
this.data = new Dictionary<string, object>();
}
/// <summary>
/// Loads the content of the specified <see cref="IResourceReader" /> into the cache.
/// </summary>
/// <param name="reader">The <see cref="IResourceReader" /> to be used to read the resource content.</param>
protected virtual void LoadContent(IResourceReader reader)
{
IDictionaryEnumerator en = reader.GetEnumerator();
while (en.MoveNext()) {
this.data.Add((string)en.Key, en.Value);
}
}
/// <summary>
/// Loads the content of the file into the cache.
/// </summary>
protected virtual void LoadContent()
{
using(IResourceReader reader = this.GetResourceReader()) {
if (reader != null) {
this.LoadContent(reader);
reader.Close();
}
}
}
/// <summary>
/// Gets a resource reader for the resource file represented by this instance.
/// </summary>
/// <returns>A resource reader for the resource file represented by this instance.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
protected virtual IResourceReader GetResourceReader()
{
return new ResourceReader(this.FileName);
}
// ********************************************************************************************************************************
/// <summary>
/// Save changes done to the resource content to disk.
/// </summary>
protected void Save()
{
this.SaveContent();
this.lastWriteTimeUtc = File.GetLastWriteTimeUtc(this.FileName);
}
/// <summary>
/// Save changes done to the resource content to disk.
/// </summary>
protected virtual void SaveContent()
{
using(IResourceWriter writer = this.GetResourceWriter()) {
if (writer != null) {
this.SaveContent(writer);
writer.Close();
}
}
}
/// <summary>
/// Save changes done to the resource content to disk.
/// </summary>
/// <param name="writer">The <see cref="IResourceWriter" /> to be used to save the resource content.</param>
protected virtual void SaveContent(IResourceWriter writer)
{
foreach (KeyValuePair<string, object> entry in this.data) {
writer.AddResource(entry.Key, entry.Value);
}
}
/// <summary>
/// Gets a resource writer for the resource file represented by this instance.
/// </summary>
/// <returns>A resource writer for the resource file represented by this instance.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
protected virtual IResourceWriter GetResourceWriter()
{
return new ResourceWriter(this.FileName);
}
// ********************************************************************************************************************************
/// <summary>
/// Gets an iterator that can be used to iterate over all key/value pairs in this resource.
/// </summary>
public IEnumerable<KeyValuePair<string, object>> Data {
get {
this.EnsureLoaded();
return this.data;
}
}
/// <summary>
/// Determines if the resource file this instance represents contains the specified key.
/// </summary>
public bool ContainsKey(string key)
{
this.EnsureLoaded();
return this.data.ContainsKey(key);
}
/// <summary>
/// Tries to get the value of the resource with the specified key.
/// </summary>
/// <returns><c>true</c>, if the key exists, otherwise <c>false</c>.</returns>
public bool TryGetValue(string key, out object value)
{
this.EnsureLoaded();
return this.data.TryGetValue(key, out value);
}
/// <summary>
/// Adds a new key to the resource file.
/// </summary>
/// <exception cref="ArgumentException">A key with the same name already exists.</exception>
public void Add(string key, object value)
{
this.EnsureLoaded();
if (this.data.ContainsKey(key)) {
throw new ArgumentException("A key with the name '"+key+"' already exists.", "key");
}
this.data.Add(key, value);
this.Save();
}
/// <summary>
/// Modify the value of an existing entry.
/// </summary>
/// <exception cref="ArgumentException">The specified key does not exist.</exception>
public void SetValue(string key, object value)
{
this.EnsureLoaded();
if (!this.data.ContainsKey(key)) {
throw new ArgumentException("The key '"+key+"' does not exist.", "key");
}
this.data[key] = value;
this.Save();
}
/// <summary>
/// Renames a resource key.
/// </summary>
/// <param name="oldName">The old name of the resource key to rename.</param>
/// <param name="newName">The new name of the resource key.</param>
/// <exception cref="ArgumentException">The specified key does not exist or the new key does already exist.</exception>
public void RenameKey(string oldName, string newName)
{
this.EnsureLoaded();
if (!this.data.ContainsKey(oldName)) {
throw new ArgumentException("The key '"+oldName+"' does not exist.", "oldName");
}
if (this.data.ContainsKey(newName)) {
throw new ArgumentException("The key '"+newName+"' already exists.", "newName");
}
this.data.Add(newName, this.data[oldName]);
this.data.Remove(oldName);
this.Save();
}
/// <summary>
/// Removes the specified resource key permanently.
/// </summary>
/// <param name="key">The resource key to remove.</param>
/// <exception cref="ArgumentException">The specified key does not exist.</exception>
public void RemoveKey(string key)
{
this.EnsureLoaded();
if (!this.data.ContainsKey(key)) {
throw new ArgumentException("The key '"+key+"' does not exist.", "key");
}
this.data.Remove(key);
this.Save();
}
}
}