WIP Gets legacy dictionary, language classes to wrap the Core services implementation properly. Obsoletes a bunch of stuff, creates a few more tests, need to test UI now.

This commit is contained in:
Shannon
2015-01-12 18:52:30 +11:00
parent 7212015127
commit ffd4e9507b
11 changed files with 603 additions and 335 deletions

View File

@@ -11,6 +11,14 @@ namespace Umbraco.Core
/// </summary>
public static class Conventions
{
public static class Localization
{
/// <summary>
/// The root id for all top level dictionary items
/// </summary>
public const string DictionaryItemRootId = "41c7638d-f529-4bff-853e-59a0c2fb1bde";
}
public static class DataTypes
{
public const string ListViewPrefix = "List View - ";

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Core.Models
private IEnumerable<IDictionaryTranslation> _translations;
public DictionaryItem(string itemKey)
: this(new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde"), itemKey)
: this(new Guid(Constants.Conventions.Localization.DictionaryItemRootId), itemKey)
{}
public DictionaryItem(Guid parentId, string itemKey)
@@ -95,7 +95,7 @@ namespace Umbraco.Core.Models
//If ParentId is not set we should default to the root parent id
if(ParentId == Guid.Empty)
_parentId = new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde");
_parentId = new Guid(Constants.Conventions.Localization.DictionaryItemRootId);
}
}

View File

@@ -18,12 +18,14 @@ namespace Umbraco.Core.Models
public DictionaryTranslation(ILanguage language, string value)
{
if (language == null) throw new ArgumentNullException("language");
_language = language;
_value = value;
}
public DictionaryTranslation(ILanguage language, string value, Guid uniqueId)
{
if (language == null) throw new ArgumentNullException("language");
_language = language;
_value = value;
Key = uniqueId;

View File

@@ -130,7 +130,7 @@ namespace Umbraco.Core.Persistence.Repositories
/// </summary>
protected override Guid NodeObjectTypeId
{
get { return new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde"); }
get { return new Guid(Constants.Conventions.Localization.DictionaryItemRootId); }
}
#endregion

View File

@@ -15,6 +15,15 @@ namespace Umbraco.Core.Services
//Add/Set Text (Insert/Update)
//Remove Text (in translation)
/// <summary>
/// Creates and saves a new dictionary item and assigns a value to all languages if defaultValue is specified.
/// </summary>
/// <param name="key"></param>
/// <param name="parentId"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
IDictionaryItem CreateDictionaryItemWithIdentity(string key, Guid? parentId, string defaultValue = null);
/// <summary>
/// Gets a <see cref="IDictionaryItem"/> by its <see cref="Int32"/> id
/// </summary>

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Core.Services
{
private readonly RepositoryFactory _repositoryFactory;
private readonly IDatabaseUnitOfWorkProvider _uowProvider;
private static readonly Guid RootParentId = new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde");
private static readonly Guid RootParentId = new Guid(Constants.Conventions.Localization.DictionaryItemRootId);
[Obsolete("Use the constructors that specify all dependencies instead")]
public LocalizationService()
@@ -44,6 +44,52 @@ namespace Umbraco.Core.Services
_uowProvider = provider;
}
/// <summary>
/// Creates and saves a new dictionary item and assigns a value to all languages if defaultValue is specified.
/// </summary>
/// <param name="key"></param>
/// <param name="parentId"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public IDictionaryItem CreateDictionaryItemWithIdentity(string key, Guid? parentId, string defaultValue = null)
{
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateDictionaryRepository(uow))
{
//validate the parent
if (parentId.HasValue && parentId.Value != Guid.Empty)
{
var parent = GetDictionaryItemById(parentId.Value);
if (parent == null)
{
throw new ArgumentException("No parent dictionary item was found with id " + parentId.Value);
}
}
var item = new DictionaryItem(parentId.HasValue ? parentId.Value : RootParentId, key);
if (defaultValue.IsNullOrWhiteSpace() == false)
{
var langs = GetAllLanguages();
var translations = langs.Select(language => new DictionaryTranslation(language, defaultValue))
.Cast<IDictionaryTranslation>()
.ToList();
item.Translations = translations;
}
if (SavingDictionaryItem.IsRaisedEventCancelled(new SaveEventArgs<IDictionaryItem>(item), this))
return item;
repository.AddOrUpdate(item);
uow.Commit();
SavedDictionaryItem.RaiseEvent(new SaveEventArgs<IDictionaryItem>(item), this);
return item;
}
}
/// <summary>
/// Gets a <see cref="IDictionaryItem"/> by its <see cref="Int32"/> id
/// </summary>

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Tests.TestHelpers;
@@ -36,7 +37,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Get_Root_Dictionary_Items()
public void Can_Get_Root_Dictionary_Items()
{
var rootItems = ServiceContext.LocalizationService.GetRootDictionaryItems();
@@ -45,14 +46,14 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Determint_If_DictionaryItem_Exists()
public void Can_Determint_If_DictionaryItem_Exists()
{
var exists = ServiceContext.LocalizationService.DictionaryItemExists("Parent");
Assert.IsTrue(exists);
}
[Test]
public void LocalizationService_Can_Get_All_Languages()
public void Can_Get_All_Languages()
{
var languages = ServiceContext.LocalizationService.GetAllLanguages();
Assert.NotNull(languages);
@@ -61,7 +62,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Get_Dictionary_Item_By_Int_Id()
public void Can_Get_Dictionary_Item_By_Int_Id()
{
var parentItem = ServiceContext.LocalizationService.GetDictionaryItemById(_parentItemIntId);
Assert.NotNull(parentItem);
@@ -71,7 +72,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Get_Dictionary_Item_By_Guid_Id()
public void Can_Get_Dictionary_Item_By_Guid_Id()
{
var parentItem = ServiceContext.LocalizationService.GetDictionaryItemById(_parentItemGuidId);
Assert.NotNull(parentItem);
@@ -81,7 +82,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Get_Dictionary_Item_By_Key()
public void Can_Get_Dictionary_Item_By_Key()
{
var parentItem = ServiceContext.LocalizationService.GetDictionaryItemByKey("Parent");
Assert.NotNull(parentItem);
@@ -91,7 +92,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Get_Dictionary_Item_Children()
public void Can_Get_Dictionary_Item_Children()
{
var item = ServiceContext.LocalizationService.GetDictionaryItemChildren(_parentItemGuidId);
Assert.NotNull(item);
@@ -104,7 +105,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Get_Language_By_Culture_Code()
public void Can_Get_Language_By_Culture_Code()
{
var danish = ServiceContext.LocalizationService.GetLanguageByCultureCode("Danish");
var english = ServiceContext.LocalizationService.GetLanguageByCultureCode("English");
@@ -113,7 +114,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_GetLanguageById()
public void Can_GetLanguageById()
{
var danish = ServiceContext.LocalizationService.GetLanguageById(_danishLangId);
var english = ServiceContext.LocalizationService.GetLanguageById(_englishLangId);
@@ -122,7 +123,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_GetLanguageByIsoCode()
public void Can_GetLanguageByIsoCode()
{
var danish = ServiceContext.LocalizationService.GetLanguageByIsoCode("da-DK");
var english = ServiceContext.LocalizationService.GetLanguageByIsoCode("en-GB");
@@ -131,21 +132,21 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Does_Not_Fail_When_Language_Doesnt_Exist()
public void Does_Not_Fail_When_Language_Doesnt_Exist()
{
var language = ServiceContext.LocalizationService.GetLanguageByIsoCode("sv-SE");
Assert.Null(language);
}
[Test]
public void LocalizationService_Does_Not_Fail_When_DictionaryItem_Doesnt_Exist()
public void Does_Not_Fail_When_DictionaryItem_Doesnt_Exist()
{
var item = ServiceContext.LocalizationService.GetDictionaryItemByKey("RandomKey");
Assert.Null(item);
}
[Test]
public void LocalizationService_Can_Delete_Language()
public void Can_Delete_Language()
{
var norwegian = new Language("nb-NO") { CultureName = "Norwegian" };
ServiceContext.LocalizationService.Save(norwegian, 0);
@@ -159,7 +160,87 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Delete_DictionaryItem()
public void Can_Create_DictionaryItem_At_Root()
{
var english = ServiceContext.LocalizationService.GetLanguageByIsoCode("en-US");
var item = (IDictionaryItem)new DictionaryItem("Testing123")
{
Translations = new List<IDictionaryTranslation>
{
new DictionaryTranslation(english, "Hello world")
}
};
ServiceContext.LocalizationService.Save(item);
//re-get
item = ServiceContext.LocalizationService.GetDictionaryItemById(item.Id);
Assert.Greater(item.Id, 0);
Assert.IsTrue(item.HasIdentity);
Assert.AreEqual(new Guid(Constants.Conventions.Localization.DictionaryItemRootId), item.ParentId);
Assert.AreEqual("Testing123", item.ItemKey);
Assert.AreEqual(1, item.Translations.Count());
}
[Test]
public void Can_Create_DictionaryItem_At_Root_With_Identity()
{
var item = ServiceContext.LocalizationService.CreateDictionaryItemWithIdentity(
"Testing12345", null, "Hellooooo");
Assert.Greater(item.Id, 0);
Assert.IsTrue(item.HasIdentity);
Assert.AreEqual(new Guid(Constants.Conventions.Localization.DictionaryItemRootId), item.ParentId);
Assert.AreEqual("Testing12345", item.ItemKey);
var allLangs = ServiceContext.LocalizationService.GetAllLanguages();
Assert.Greater(allLangs.Count(), 0);
foreach (var language in allLangs)
{
Assert.AreEqual("Hellooooo", item.Translations.Single(x => x.Language.CultureName == language.CultureName).Value);
}
}
[Test]
public void Can_Add_Translation_To_Existing_Dictionary_Item()
{
var english = ServiceContext.LocalizationService.GetLanguageByIsoCode("en-US");
var item = (IDictionaryItem)new DictionaryItem("Testing123")
{
Translations = new List<IDictionaryTranslation>
{
new DictionaryTranslation(english, "Hello world")
}
};
ServiceContext.LocalizationService.Save(item);
//re-get
item = ServiceContext.LocalizationService.GetDictionaryItemById(item.Id);
var newTranslations = new List<IDictionaryTranslation>(item.Translations)
{
new DictionaryTranslation(
ServiceContext.LocalizationService.GetLanguageByIsoCode("en-GB"),
"My new value")
};
item.Translations = newTranslations;
ServiceContext.LocalizationService.Save(item);
//re-get
item = ServiceContext.LocalizationService.GetDictionaryItemById(item.Id);
Assert.AreEqual(2, item.Translations.Count());
foreach (var translation in item.Translations)
{
Assert.AreEqual(translation.Language.CultureName == "en-US" ? "Hello world" : "My new value", translation.Value);
}
}
[Test]
public void Can_Delete_DictionaryItem()
{
var item = ServiceContext.LocalizationService.GetDictionaryItemByKey("Child");
Assert.NotNull(item);
@@ -171,7 +252,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void LocalizationService_Can_Update_Existing_DictionaryItem()
public void Can_Update_Existing_DictionaryItem()
{
var item = ServiceContext.LocalizationService.GetDictionaryItemByKey("Child");
foreach (var translation in item.Translations)
@@ -190,40 +271,6 @@ namespace Umbraco.Tests.Services
}
}
public override void CreateTestData()
{
var danish = new Language("da-DK") { CultureName = "Danish" };
var english = new Language("en-GB") { CultureName = "English"};
ServiceContext.LocalizationService.Save(danish, 0);
ServiceContext.LocalizationService.Save(english, 0);
_danishLangId = danish.Id;
_englishLangId = english.Id;
var parentItem = new DictionaryItem("Parent")
{
Translations = new List<IDictionaryTranslation>
{
new DictionaryTranslation(english, "ParentValue"),
new DictionaryTranslation(danish, "ForældreVærdi")
}
};
ServiceContext.LocalizationService.Save(parentItem);
_parentItemGuidId = parentItem.Key;
_parentItemIntId = parentItem.Id;
var childItem = new DictionaryItem(parentItem.Key, "Child")
{
Translations = new List<IDictionaryTranslation>
{
new DictionaryTranslation(english, "ChildValue"),
new DictionaryTranslation(danish, "BørnVærdi")
}
};
ServiceContext.LocalizationService.Save(childItem);
_childItemGuidId = childItem.Key;
_childItemIntId = childItem.Id;
}
[Test]
public void Find_BaseData_Language()
{
@@ -284,5 +331,39 @@ namespace Umbraco.Tests.Services
Assert.Null(result);
}
public override void CreateTestData()
{
var danish = new Language("da-DK") { CultureName = "Danish" };
var english = new Language("en-GB") { CultureName = "English" };
ServiceContext.LocalizationService.Save(danish, 0);
ServiceContext.LocalizationService.Save(english, 0);
_danishLangId = danish.Id;
_englishLangId = english.Id;
var parentItem = new DictionaryItem("Parent")
{
Translations = new List<IDictionaryTranslation>
{
new DictionaryTranslation(english, "ParentValue"),
new DictionaryTranslation(danish, "ForældreVærdi")
}
};
ServiceContext.LocalizationService.Save(parentItem);
_parentItemGuidId = parentItem.Key;
_parentItemIntId = parentItem.Id;
var childItem = new DictionaryItem(parentItem.Key, "Child")
{
Translations = new List<IDictionaryTranslation>
{
new DictionaryTranslation(english, "ChildValue"),
new DictionaryTranslation(danish, "BørnVærdi")
}
};
ServiceContext.LocalizationService.Save(childItem);
_childItemGuidId = childItem.Key;
_childItemIntId = childItem.Id;
}
}
}

View File

@@ -28,18 +28,18 @@ namespace Umbraco.Web.Cache
public override void Refresh(int id)
{
RuntimeCacheProvider.Current.Clear(typeof(IDictionaryItem));
global::umbraco.cms.businesslogic.Dictionary.ClearCache();
//global::umbraco.cms.businesslogic.Dictionary.ClearCache();
//when a dictionary item is updated we must also clear the text cache!
global::umbraco.cms.businesslogic.language.Item.ClearCache();
//global::umbraco.cms.businesslogic.language.Item.ClearCache();
base.Refresh(id);
}
public override void Remove(int id)
{
RuntimeCacheProvider.Current.Clear(typeof(IDictionaryItem));
global::umbraco.cms.businesslogic.Dictionary.ClearCache();
//global::umbraco.cms.businesslogic.Dictionary.ClearCache();
//when a dictionary item is removed we must also clear the text cache!
global::umbraco.cms.businesslogic.language.Item.ClearCache();
//global::umbraco.cms.businesslogic.language.Item.ClearCache();
base.Remove(id);
}
}

View File

@@ -36,7 +36,7 @@ namespace Umbraco.Web.Cache
{
RuntimeCacheProvider.Current.Clear(typeof(ILanguage));
//when a language is removed we must also clear the text cache!
global::umbraco.cms.businesslogic.language.Item.ClearCache();
//global::umbraco.cms.businesslogic.language.Item.ClearCache();
base.Remove(id);
}
}

View File

@@ -1,15 +1,19 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Data;
using System.Globalization;
using System.Threading;
using System.Xml;
using System.Linq;
using Umbraco.Core;
using umbraco.cms.businesslogic.language;
using Umbraco.Core.Models;
using umbraco.DataLayer;
using umbraco.BusinessLogic;
using System.Runtime.CompilerServices;
using Language = umbraco.cms.businesslogic.language.Language;
namespace umbraco.cms.businesslogic
{
@@ -20,57 +24,58 @@ namespace umbraco.cms.businesslogic
/// </summary>
public class Dictionary
{
private static volatile bool _cacheIsEnsured = false;
private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
private static readonly ConcurrentDictionary<string, DictionaryItem> DictionaryItems = new ConcurrentDictionary<string, DictionaryItem>();
private static readonly Guid TopLevelParent = new Guid("41c7638d-f529-4bff-853e-59a0c2fb1bde");
//private static volatile bool _cacheIsEnsured = false;
//private static readonly ReaderWriterLockSlim Locker = new ReaderWriterLockSlim();
//private static readonly ConcurrentDictionary<string, DictionaryItem> DictionaryItems = new ConcurrentDictionary<string, DictionaryItem>();
private static readonly Guid TopLevelParent = new Guid(Constants.Conventions.Localization.DictionaryItemRootId);
protected static ISqlHelper SqlHelper
{
get { return Application.SqlHelper; }
}
///// <summary>
///// Reads all items from the database and stores in local cache
///// </summary>
//private static void EnsureCache()
//{
// using (var lck = new UpgradeableReadLock(Locker))
// {
// if (_cacheIsEnsured) return;
/// <summary>
/// Reads all items from the database and stores in local cache
/// </summary>
private static void EnsureCache()
{
using (var lck = new UpgradeableReadLock(Locker))
{
if (_cacheIsEnsured) return;
lck.UpgradeToWriteLock();
// lck.UpgradeToWriteLock();
using (var dr = SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary"))
{
while (dr.Read())
{
//create new dictionaryitem object and put in cache
var item = new DictionaryItem(dr.GetInt("pk"),
dr.GetString("key"),
dr.GetGuid("id"),
dr.GetGuid("parent"));
// using (var dr = SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary"))
// {
// while (dr.Read())
// {
// //create new dictionaryitem object and put in cache
// var item = new DictionaryItem(dr.GetInt("pk"),
// dr.GetString("key"),
// dr.GetGuid("id"),
// dr.GetGuid("parent"));
DictionaryItems.TryAdd(item.key, item);
}
}
// DictionaryItems.TryAdd(item.key, item);
// }
// }
_cacheIsEnsured = true;
}
}
// _cacheIsEnsured = true;
// }
//}
/// <summary>
/// Used by the cache refreshers to clear the cache on distributed servers
/// </summary>
internal static void ClearCache()
{
using (new WriteLock(Locker))
{
DictionaryItems.Clear();
//ensure the flag is reset so that EnsureCache will re-cache everything
_cacheIsEnsured = false;
}
}
///// <summary>
///// Used by the cache refreshers to clear the cache on distributed servers
///// </summary>
//internal static void ClearCache()
//{
// using (new WriteLock(Locker))
// {
// DictionaryItems.Clear();
// //ensure the flag is reset so that EnsureCache will re-cache everything
// _cacheIsEnsured = false;
// }
//}
/// <summary>
/// Retrieve a list of toplevel DictionaryItems
@@ -79,11 +84,15 @@ namespace umbraco.cms.businesslogic
{
get
{
EnsureCache();
return DictionaryItems.Values
.Where(x => x.ParentId == TopLevelParent).OrderBy(item => item.key)
return ApplicationContext.Current.Services.LocalizationService.GetRootDictionaryItems()
.Select(x => new DictionaryItem(x))
.ToArray();
//EnsureCache();
//return DictionaryItems.Values
// .Where(x => x.ParentId == TopLevelParent).OrderBy(item => item.key)
// .ToArray();
}
}
@@ -93,90 +102,106 @@ namespace umbraco.cms.businesslogic
/// </summary>
public class DictionaryItem
{
private string _key;
internal Guid UniqueId { get; private set; }
internal Guid ParentId { get; private set; }
/// <summary>
/// Used internally to construct a new item object and store in cache
/// </summary>
/// <param name="id"></param>
/// <param name="key"></param>
/// <param name="uniqueKey"></param>
/// <param name="parentId"></param>
internal DictionaryItem(int id, string key, Guid uniqueKey, Guid parentId)
public DictionaryItem()
{
this.id = id;
this._key = key;
this.UniqueId = uniqueKey;
this.ParentId = parentId;
}
internal DictionaryItem(IDictionaryItem item)
{
_dictionaryItem = item;
//this.id = id;
//this._key = key;
//this.UniqueId = item.Key;
//this.ParentId = item.ParentId;
}
private readonly IDictionaryItem _dictionaryItem;
private DictionaryItem _parent;
//private string _key;
//internal Guid UniqueId { get; private set; }
//internal Guid ParentId { get; private set; }
///// <summary>
///// Used internally to construct a new item object and store in cache
///// </summary>
///// <param name="id"></param>
///// <param name="key"></param>
///// <param name="uniqueKey"></param>
///// <param name="parentId"></param>
//internal DictionaryItem(int id, string key, Guid uniqueKey, Guid parentId)
//{
// this.id = id;
// this._key = key;
// this.UniqueId = uniqueKey;
// this.ParentId = parentId;
//}
public DictionaryItem(string key)
{
EnsureCache();
//EnsureCache();
var item = DictionaryItems.Values.SingleOrDefault(x => x.key == key);
//var item = DictionaryItems.Values.SingleOrDefault(x => x.key == key);
_dictionaryItem = ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemByKey(key);
if (item == null)
if (_dictionaryItem == null)
{
throw new ArgumentException("No key " + key + " exists in dictionary");
}
this.id = item.id;
this._key = item.key;
this.ParentId = item.ParentId;
this.UniqueId = item.UniqueId;
//this.id = item.Id;
//this._key = item.ItemKey;
//this.ParentId = item.ParentId;
//this.UniqueId = item.Key;
}
public DictionaryItem(Guid id)
{
EnsureCache();
//EnsureCache();
var item = DictionaryItems.Values.SingleOrDefault(x => x.UniqueId == id);
//var item = DictionaryItems.Values.SingleOrDefault(x => x.UniqueId == id);
_dictionaryItem = ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemById(id);
if (item == null)
if (_dictionaryItem == null)
{
throw new ArgumentException("No unique id " + id.ToString() + " exists in dictionary");
throw new ArgumentException("No unique id " + id + " exists in dictionary");
}
this.id = item.id;
this._key = item.key;
this.ParentId = item.ParentId;
this.UniqueId = item.UniqueId;
//this.id = item.Id;
//this._key = item.ItemKey;
//this.ParentId = item.ParentId;
//this.UniqueId = item.Key;
}
public DictionaryItem(int id)
{
EnsureCache();
//EnsureCache();
var item = DictionaryItems.Values.SingleOrDefault(x => x.id == id);
_dictionaryItem = ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemById(id);
if (item == null)
if (_dictionaryItem == null)
{
throw new ArgumentException("No id " + id + " exists in dictionary");
}
this.id = item.id;
this._key = item.key;
this.ParentId = item.ParentId;
this.UniqueId = item.UniqueId;
//this.id = item.Id;
//this._key = item.ItemKey;
//this.ParentId = item.ParentId;
//this.UniqueId = item.Key;
}
private DictionaryItem _parent;
/// <summary>
/// Returns if the dictionaryItem is the root item.
/// </summary>
[Obsolete("This is no longer used and will be removed from the codebase in future versions")]
public bool IsTopMostItem()
{
EnsureCache();
return DictionaryItems.Values
.Where(x => x.id == id)
.Select(x => x.ParentId)
.SingleOrDefault() == TopLevelParent;
//EnsureCache();
//return DictionaryItems.Values
// .Where(x => x.id == id)
// .Select(x => x.ParentId)
// .SingleOrDefault() == TopLevelParent;
return _dictionaryItem.ParentId == new Guid(Constants.Conventions.Localization.DictionaryItemRootId);
}
/// <summary>
@@ -186,10 +211,12 @@ namespace umbraco.cms.businesslogic
{
get
{
EnsureCache();
//EnsureCache();
if (_parent == null)
{
var p = DictionaryItems.Values.SingleOrDefault(x => x.UniqueId == this.ParentId);
//var p = DictionaryItems.Values.SingleOrDefault(x => x.UniqueId == this.ParentId);
var p = ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemById(_dictionaryItem.ParentId);
if (p == null)
{
@@ -197,7 +224,7 @@ namespace umbraco.cms.businesslogic
}
else
{
_parent = p;
_parent = new DictionaryItem(p);
}
}
@@ -210,33 +237,41 @@ namespace umbraco.cms.businesslogic
/// </summary>
public int id
{
get;
private set;
get { return _dictionaryItem.Id; }
}
public DictionaryItem[] Children
{
get
{
EnsureCache();
return DictionaryItems.Values
.Where(x => x.ParentId == this.UniqueId).OrderBy(item => item.key)
return ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemChildren(_dictionaryItem.Key)
.WhereNotNull()
.Select(x => new DictionaryItem(x))
.ToArray();
//EnsureCache();
//return DictionaryItems.Values
// .Where(x => x.ParentId == this.UniqueId).OrderBy(item => item.key)
// .ToArray();
}
}
public static bool hasKey(string key)
{
EnsureCache();
return DictionaryItems.ContainsKey(key);
return ApplicationContext.Current.Services.LocalizationService.DictionaryItemExists(key);
//EnsureCache();
//return DictionaryItems.ContainsKey(key);
}
public bool hasChildren
{
get
{
EnsureCache();
return DictionaryItems.Values.Any(x => x.ParentId == UniqueId);
//EnsureCache();
//return DictionaryItems.Values.Any(x => x.ParentId == UniqueId);
return Children.Any();
}
}
@@ -245,37 +280,38 @@ namespace umbraco.cms.businesslogic
/// </summary>
public string key
{
get { return _key; }
get { return _dictionaryItem.ItemKey; }
set
{
if (!hasKey(value))
if (hasKey(value) == false)
{
lock (Locker)
{
SqlHelper.ExecuteNonQuery("Update cmsDictionary set [key] = @key WHERE pk = @Id", SqlHelper.CreateParameter("@key", value),
SqlHelper.CreateParameter("@Id", id));
using (IRecordsReader dr =
SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary where id=@id",
SqlHelper.CreateParameter("@id", this.UniqueId)))
{
if (dr.Read())
{
//create new dictionaryitem object and put in cache
var item = new DictionaryItem(dr.GetInt("pk"),
dr.GetString("key"),
dr.GetGuid("id"),
dr.GetGuid("parent"));
}
else
{
throw new DataException("Could not load updated created dictionary item with id " + id);
}
}
//lock (Locker)
//{
// SqlHelper.ExecuteNonQuery("Update cmsDictionary set [key] = @key WHERE pk = @Id", SqlHelper.CreateParameter("@key", value),
// SqlHelper.CreateParameter("@Id", id));
//finally update this objects value
this._key = value;
}
// using (IRecordsReader dr =
// SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary where id=@id",
// SqlHelper.CreateParameter("@id", this.UniqueId)))
// {
// if (dr.Read())
// {
// //create new dictionaryitem object and put in cache
// var item = new DictionaryItem(dr.GetInt("pk"),
// dr.GetString("key"),
// dr.GetGuid("id"),
// dr.GetGuid("parent"));
// }
// else
// {
// throw new DataException("Could not load updated created dictionary item with id " + id);
// }
// }
// //finally update this objects value
// this._key = value;
//}
_dictionaryItem.ItemKey = value;
}
else
throw new ArgumentException("New value of key already exists (is key)");
@@ -287,43 +323,56 @@ namespace umbraco.cms.businesslogic
if (languageId == 0)
return Value();
if (Item.hasText(UniqueId, languageId))
return Item.Text(UniqueId, languageId);
var translation = _dictionaryItem.Translations.FirstOrDefault(x => x.Language.Id == languageId);
return translation == null ? string.Empty : translation.Value;
return "";
//if (Item.hasText(_dictionaryItem.Key, languageId))
// return Item.Text(_dictionaryItem.Key, languageId);
//return "";
}
public void setValue(int languageId, string value)
{
if (Item.hasText(UniqueId, languageId))
Item.setText(languageId, UniqueId, value);
else
Item.addText(languageId, UniqueId, value);
foreach (var translation in _dictionaryItem.Translations.Where(x => x.Language.Id == languageId))
{
translation.Value = value;
}
//if (Item.hasText(_dictionaryItem.Key, languageId))
// Item.setText(languageId, _dictionaryItem.Key, value);
//else
// Item.addText(languageId, _dictionaryItem.Key, value);
// Calling Save method triggers the Saving event
Save();
}
/// <summary>
/// Returns the default value based on the default language for this item
/// </summary>
/// <returns></returns>
public string Value()
{
if (Item.hasText(UniqueId, 1))
{
return Item.Text(UniqueId, 1);
}
var defaultTranslation = _dictionaryItem.Translations.FirstOrDefault(x => x.Language.Id == 1);
return defaultTranslation == null ? string.Empty : defaultTranslation.Value;
return string.Empty;
//if (Item.hasText(_dictionaryItem.Key, 1))
//{
// return Item.Text(_dictionaryItem.Key, 1);
//}
//return string.Empty;
}
/// <summary>
/// This sets the value for the placeholder language (id = 0), not for a language with an ID
/// </summary>
/// <param name="value"></param>
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This is not used and should never be used, it will be removed from the codebase in future versions")]
public void setValue(string value)
{
if (Item.hasText(UniqueId, 0))
Item.setText(0, UniqueId, value);
if (Item.hasText(_dictionaryItem.Key, 0))
Item.setText(0, _dictionaryItem.Key, value);
else
Item.addText(0, UniqueId, value);
Item.addText(0, _dictionaryItem.Key, value);
// Calling Save method triggers the Saving event
Save();
@@ -331,11 +380,11 @@ namespace umbraco.cms.businesslogic
public static int addKey(string key, string defaultValue, string parentKey)
{
EnsureCache();
//EnsureCache();
if (hasKey(parentKey))
{
int retval = createKey(key, new DictionaryItem(parentKey).UniqueId, defaultValue);
int retval = CreateKey(key, new DictionaryItem(parentKey)._dictionaryItem.Key, defaultValue);
return retval;
}
else
@@ -344,8 +393,9 @@ namespace umbraco.cms.businesslogic
public static int addKey(string key, string defaultValue)
{
EnsureCache();
int retval = createKey(key, TopLevelParent, defaultValue);
//EnsureCache();
int retval = CreateKey(key, TopLevelParent, defaultValue);
return retval;
}
@@ -353,15 +403,17 @@ namespace umbraco.cms.businesslogic
{
OnDeleting(EventArgs.Empty);
// delete recursive
foreach (DictionaryItem dd in Children)
dd.delete();
ApplicationContext.Current.Services.LocalizationService.Delete(_dictionaryItem);
// remove all language values from key
Item.removeText(UniqueId);
//// delete recursive
//foreach (DictionaryItem dd in Children)
// dd.delete();
// remove key from database
SqlHelper.ExecuteNonQuery("delete from cmsDictionary where [key] = @key", SqlHelper.CreateParameter("@key", key));
//// remove all language values from key
//Item.removeText(_dictionaryItem.Key);
//// remove key from database
//SqlHelper.ExecuteNonQuery("delete from cmsDictionary where [key] = @key", SqlHelper.CreateParameter("@key", key));
OnDeleted(EventArgs.Empty);
}
@@ -372,10 +424,12 @@ namespace umbraco.cms.businesslogic
public void Save()
{
OnSaving(EventArgs.Empty);
ApplicationContext.Current.Services.LocalizationService.Save(_dictionaryItem);
}
public System.Xml.XmlNode ToXml(XmlDocument xd)
public XmlNode ToXml(XmlDocument xd)
{
XmlNode dictionaryItem = xd.CreateElement("DictionaryItem");
@@ -383,7 +437,7 @@ namespace umbraco.cms.businesslogic
foreach (Language lang in Language.GetAllAsList())
{
XmlNode itemValue = xmlHelper.addCDataNode(xd, "Value", this.Value(lang.id));
itemValue.Attributes.Append(xmlHelper.addAttribute(xd, "LanguageId", lang.id.ToString()));
itemValue.Attributes.Append(xmlHelper.addAttribute(xd, "LanguageId", lang.id.ToString(CultureInfo.InvariantCulture)));
itemValue.Attributes.Append(xmlHelper.addAttribute(xd, "LanguageCultureAlias", lang.CultureAlias));
dictionaryItem.AppendChild(itemValue);
}
@@ -456,40 +510,43 @@ namespace umbraco.cms.businesslogic
return null;
}
[MethodImpl(MethodImplOptions.Synchronized)]
private static int createKey(string key, Guid parentId, string defaultValue)
private static int CreateKey(string key, Guid parentId, string defaultValue)
{
if (!hasKey(key))
{
Guid newId = Guid.NewGuid();
SqlHelper.ExecuteNonQuery("Insert into cmsDictionary (id,parent,[key]) values (@id, @parentId, @dictionaryKey)",
SqlHelper.CreateParameter("@id", newId),
SqlHelper.CreateParameter("@parentId", parentId),
SqlHelper.CreateParameter("@dictionaryKey", key));
var item = ApplicationContext.Current.Services.LocalizationService.CreateDictionaryItemWithIdentity(
key, parentId, defaultValue);
using (IRecordsReader dr =
SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary where id=@id",
SqlHelper.CreateParameter("@id", newId)))
{
if (dr.Read())
{
//create new dictionaryitem object and put in cache
var item = new DictionaryItem(dr.GetInt("pk"),
dr.GetString("key"),
dr.GetGuid("id"),
dr.GetGuid("parent"));
item.setValue(defaultValue);
return item.Id;
item.OnNew(EventArgs.Empty);
//SqlHelper.ExecuteNonQuery("Insert into cmsDictionary (id,parent,[key]) values (@id, @parentId, @dictionaryKey)",
// SqlHelper.CreateParameter("@id", newId),
// SqlHelper.CreateParameter("@parentId", parentId),
// SqlHelper.CreateParameter("@dictionaryKey", key));
return item.id;
}
else
{
throw new DataException("Could not load newly created dictionary item with id " + newId.ToString());
}
}
//using (IRecordsReader dr =
// SqlHelper.ExecuteReader("Select pk, id, [key], parent from cmsDictionary where id=@id",
// SqlHelper.CreateParameter("@id", newId)))
//{
// if (dr.Read())
// {
// //create new dictionaryitem object and put in cache
// var item = new DictionaryItem(dr.GetInt("pk"),
// dr.GetString("key"),
// dr.GetGuid("id"),
// dr.GetGuid("parent"));
// item.setValue(defaultValue);
// item.OnNew(EventArgs.Empty);
// return item.id;
// }
// else
// {
// throw new DataException("Could not load newly created dictionary item with id " + newId.ToString());
// }
//}
}
else
@@ -540,16 +597,16 @@ namespace umbraco.cms.businesslogic
return text;
var lang = Language.GetByCultureCode(Thread.CurrentThread.CurrentCulture.Name);
if (lang == null)
return "[" + text + "]";
if (DictionaryItem.hasKey(text.Substring(1, text.Length - 1)) == false)
if (DictionaryItem.hasKey(text.Substring(1, text.Length - 1)) == false)
return "[" + text + "]";
var di = new DictionaryItem(text.Substring(1, text.Length - 1));
return di.Value(lang.id);
}
}
}

View File

@@ -1,10 +1,12 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Data;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.SqlSyntax;
using umbraco.DataLayer;
@@ -14,19 +16,13 @@ using Umbraco.Core.Models.Rdbms;
namespace umbraco.cms.businesslogic.language
{
/// <summary>
/// THIS CLASS IS NOT INTENDED TO BE USED DIRECTLY IN YOUR CODE, USE THE umbraco.cms.businesslogic.Dictionary class instead
/// </summary>
/// <remarks>
/// This class is used by the DictionaryItem, all caching is handled in the DictionaryItem.Save() method which will ensure that
/// cache is invalidated if anything is changed.
/// </remarks>
[Obsolete("THIS CLASS IS NOT INTENDED TO BE USED DIRECTLY IN YOUR CODE, USE THE umbraco.cms.businesslogic.Dictionary class instead")]
[EditorBrowsable(EditorBrowsableState.Never)]
[Obsolete("This class is no longer used, nor should it ever be used, it will be removed from the codebase in future versions")]
public class Item
{
private static readonly ConcurrentDictionary<Guid, Dictionary<int, string>> Items = new ConcurrentDictionary<Guid, Dictionary<int, string>>();
private static volatile bool _isInitialize;
private static readonly object Locker = new object();
//private static readonly ConcurrentDictionary<Guid, Dictionary<int, string>> Items = new ConcurrentDictionary<Guid, Dictionary<int, string>>();
//private static volatile bool _isInitialize;
//private static readonly object Locker = new object();
/// <summary>
/// Gets the SQL helper.
@@ -38,54 +34,54 @@ namespace umbraco.cms.businesslogic.language
get { return Application.SqlHelper; }
}
/// <summary>
/// Populates the global hash table with the data from the database.
/// </summary>
private static void EnsureCache()
{
if (!_isInitialize)
{
lock (Locker)
{
//double check
if (!_isInitialize)
{
///// <summary>
///// Populates the global hash table with the data from the database.
///// </summary>
//private static void EnsureCache()
//{
// if (!_isInitialize)
// {
// lock (Locker)
// {
// //double check
// if (!_isInitialize)
// {
var dtos = ApplicationContext.Current.DatabaseContext.Database.Fetch<LanguageTextDto>("ORDER BY UniqueId");
foreach (var dto in dtos)
{
var languageId = dto.LanguageId;
var uniqueId = dto.UniqueId;
var text = dto.Value;
// var dtos = ApplicationContext.Current.DatabaseContext.Database.Fetch<LanguageTextDto>("ORDER BY UniqueId");
// foreach (var dto in dtos)
// {
// var languageId = dto.LanguageId;
// var uniqueId = dto.UniqueId;
// var text = dto.Value;
Items.AddOrUpdate(uniqueId, guid =>
{
var languagevalues = new Dictionary<int, string> { { languageId, text } };
return languagevalues;
}, (guid, dictionary) =>
{
// add/update the text for the id
dictionary[languageId] = text;
return dictionary;
});
}
// Items.AddOrUpdate(uniqueId, guid =>
// {
// var languagevalues = new Dictionary<int, string> { { languageId, text } };
// return languagevalues;
// }, (guid, dictionary) =>
// {
// // add/update the text for the id
// dictionary[languageId] = text;
// return dictionary;
// });
// }
_isInitialize = true;
}
}
// _isInitialize = true;
// }
// }
}
}
// }
//}
/// <summary>
/// Clears the cache, this is used for cache refreshers to ensure that the cache is up to date across all servers
/// </summary>
internal static void ClearCache()
{
Items.Clear();
//reset the flag so that we re-lookup the cache
_isInitialize = false;
}
///// <summary>
///// Clears the cache, this is used for cache refreshers to ensure that the cache is up to date across all servers
///// </summary>
//internal static void ClearCache()
//{
// Items.Clear();
// //reset the flag so that we re-lookup the cache
// _isInitialize = false;
//}
/// <summary>
/// Retrieves the value of a languagetranslated item given the key
@@ -95,13 +91,24 @@ namespace umbraco.cms.businesslogic.language
/// <returns>The language translated text</returns>
public static string Text(Guid key, int languageId)
{
EnsureCache();
//EnsureCache();
Dictionary<int, string> val;
if (Items.TryGetValue(key, out val))
//Dictionary<int, string> val;
//if (Items.TryGetValue(key, out val))
//{
// return val[languageId];
//}
var item = ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemById(key);
if (item != null)
{
return val[languageId];
}
var translation = item.Translations.FirstOrDefault(x => x.Language.Id == languageId);
if (translation != null)
{
return translation.Value;
}
}
throw new ArgumentException("Key being requested does not exist");
}
@@ -113,14 +120,23 @@ namespace umbraco.cms.businesslogic.language
/// <returns>returns True if there is a value associated to the unique identifier with the specified language</returns>
public static bool hasText(Guid key, int languageId)
{
EnsureCache();
//EnsureCache();
Dictionary<int, string> val;
if (Items.TryGetValue(key, out val))
//Dictionary<int, string> val;
//if (Items.TryGetValue(key, out val))
//{
// return val.ContainsKey(languageId);
//}
//return false;
try
{
return val.ContainsKey(languageId);
return Text(key, languageId).IsNullOrWhiteSpace() == false;
}
catch (ArgumentException)
{
return false;
}
return false;
}
/// <summary>
@@ -133,12 +149,31 @@ namespace umbraco.cms.businesslogic.language
public static void setText(int languageId, Guid key, string value)
{
if (!hasText(key, languageId)) throw new ArgumentException("Key does not exist");
var lang = ApplicationContext.Current.Services.LocalizationService.GetLanguageById(languageId);
if (lang == null) return;
var item = ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemById(key);
if (item != null)
{
var translation = item.Translations.FirstOrDefault(x => x.Language.Id == languageId);
if (translation == null)
{
throw new ArgumentException("Key does not exist");
}
var newTranslations = new List<IDictionaryTranslation>(item.Translations)
{
new DictionaryTranslation(lang, value)
};
item.Translations = newTranslations;
ApplicationContext.Current.Services.LocalizationService.Save(item);
}
//if (!hasText(key, languageId)) throw new ArgumentException("Key does not exist");
ApplicationContext.Current.DatabaseContext.Database.Update<LanguageTextDto>(
string.Format("set {0} = @value where LanguageId = @languageId And UniqueId = @key",
SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("value")),
new {value = value, languageId = languageId, key = key});
//ApplicationContext.Current.DatabaseContext.Database.Update<LanguageTextDto>(
// string.Format("set {0} = @value where LanguageId = @languageId And UniqueId = @key",
// SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("value")),
// new {value = value, languageId = languageId, key = key});
}
/// <summary>
@@ -150,14 +185,33 @@ namespace umbraco.cms.businesslogic.language
/// <param name="value"></param>
public static void addText(int languageId, Guid key, string value)
{
if (hasText(key, languageId)) throw new ArgumentException("Key being add'ed already exists");
var lang = ApplicationContext.Current.Services.LocalizationService.GetLanguageById(languageId);
if (lang == null) return;
ApplicationContext.Current.DatabaseContext.Database.Insert(new LanguageTextDto
{
LanguageId = languageId,
Value = value,
UniqueId = key
});
var item = ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemById(key);
if (item != null)
{
var translation = item.Translations.FirstOrDefault(x => x.Language.Id == languageId);
if (translation != null)
{
throw new ArgumentException("Key being add'ed already exists");
}
var newTranslations = new List<IDictionaryTranslation>(item.Translations)
{
new DictionaryTranslation(lang, value)
};
item.Translations = newTranslations;
ApplicationContext.Current.Services.LocalizationService.Save(item);
}
//if (hasText(key, languageId)) throw new ArgumentException("Key being add'ed already exists");
//ApplicationContext.Current.DatabaseContext.Database.Insert(new LanguageTextDto
// {
// LanguageId = languageId,
// Value = value,
// UniqueId = key
// });
}
/// <summary>
@@ -166,8 +220,13 @@ namespace umbraco.cms.businesslogic.language
/// <param name="key">Unique identifier</param>
public static void removeText(Guid key)
{
// remove from database
ApplicationContext.Current.DatabaseContext.Database.Delete<LanguageTextDto>("where UniqueId = @UniqueId", new { UniqueId = key });
//// remove from database
//ApplicationContext.Current.DatabaseContext.Database.Delete<LanguageTextDto>("where UniqueId = @UniqueId", new { UniqueId = key });
var found = ApplicationContext.Current.Services.LocalizationService.GetDictionaryItemById(key);
if (found != null)
{
ApplicationContext.Current.Services.LocalizationService.Delete(found);
}
}
/// <summary>
@@ -178,8 +237,14 @@ namespace umbraco.cms.businesslogic.language
[Obsolete("This is no longer used and will be removed from the codebase in future versions")]
public static void RemoveByLanguage(int languageId)
{
// remove from database
ApplicationContext.Current.DatabaseContext.Database.Delete<LanguageTextDto>("where languageId = @languageId", new { languageId = languageId });
var lang = ApplicationContext.Current.Services.LocalizationService.GetLanguageById(languageId);
if (lang != null)
{
ApplicationContext.Current.Services.LocalizationService.Delete(lang);
}
//// remove from database
//ApplicationContext.Current.DatabaseContext.Database.Delete<LanguageTextDto>("where languageId = @languageId", new { languageId = languageId });
}
}
}