mirror of https://github.com/Squidex/squidex.git
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.
183 lines
5.5 KiB
183 lines
5.5 KiB
// ==========================================================================
|
|
// LanguagesConfig.cs
|
|
// Squidex Headless CMS
|
|
// ==========================================================================
|
|
// Copyright (c) Squidex Group
|
|
// All rights reserved.
|
|
// ==========================================================================
|
|
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using Squidex.Infrastructure;
|
|
|
|
#pragma warning disable IDE0016 // Use 'throw' expression
|
|
|
|
namespace Squidex.Domain.Apps.Core.Apps
|
|
{
|
|
public sealed class LanguagesConfig : IFieldPartitioning
|
|
{
|
|
private State state;
|
|
|
|
public LanguageConfig Master
|
|
{
|
|
get { return state.Master; }
|
|
}
|
|
|
|
IFieldPartitionItem IFieldPartitioning.Master
|
|
{
|
|
get { return state.Master; }
|
|
}
|
|
|
|
IEnumerator IEnumerable.GetEnumerator()
|
|
{
|
|
return state.Languages.Values.GetEnumerator();
|
|
}
|
|
|
|
IEnumerator<IFieldPartitionItem> IEnumerable<IFieldPartitionItem>.GetEnumerator()
|
|
{
|
|
return state.Languages.Values.GetEnumerator();
|
|
}
|
|
|
|
public IEnumerable<LanguageConfig> Configs
|
|
{
|
|
get { return state.Languages.Values; }
|
|
}
|
|
|
|
public int Count
|
|
{
|
|
get { return state.Languages.Count; }
|
|
}
|
|
|
|
private LanguagesConfig(ICollection<LanguageConfig> configs)
|
|
{
|
|
Guard.NotNull(configs, nameof(configs));
|
|
|
|
state = new State(configs.ToImmutableDictionary(x => x.Language), configs.FirstOrDefault());
|
|
}
|
|
|
|
public static LanguagesConfig Build(params LanguageConfig[] configs)
|
|
{
|
|
Guard.NotNull(configs, nameof(configs));
|
|
|
|
return new LanguagesConfig(configs);
|
|
}
|
|
|
|
public static LanguagesConfig Build(params Language[] languages)
|
|
{
|
|
Guard.NotNull(languages, nameof(languages));
|
|
|
|
return new LanguagesConfig(languages.Select(x => new LanguageConfig(x, false)).ToList());
|
|
}
|
|
|
|
public void MakeMaster(Language language)
|
|
{
|
|
Guard.NotNull(language, nameof(language));
|
|
|
|
state = new State(state.Languages, state.Languages[language]);
|
|
}
|
|
|
|
public void Set(LanguageConfig config)
|
|
{
|
|
Guard.NotNull(config, nameof(config));
|
|
|
|
state = new State(state.Languages.SetItem(config.Language, config), state.Master?.Language == config.Language ? config : state.Master);
|
|
}
|
|
|
|
public void Remove(Language language)
|
|
{
|
|
Guard.NotNull(language, nameof(language));
|
|
|
|
var newLanguages =
|
|
state.Languages.Values.Where(x => x.Language != language)
|
|
.Select(config =>
|
|
{
|
|
return new LanguageConfig(
|
|
config.Language,
|
|
config.IsOptional,
|
|
config.LanguageFallbacks.Except(new[] { language }));
|
|
})
|
|
.ToImmutableDictionary(x => x.Language);
|
|
|
|
var newMaster =
|
|
state.Master.Language != language ?
|
|
state.Master :
|
|
state.Languages.Values.FirstOrDefault();
|
|
|
|
state = new State(newLanguages, newMaster);
|
|
}
|
|
|
|
public bool Contains(Language language)
|
|
{
|
|
return language != null && state.Languages.ContainsKey(language);
|
|
}
|
|
|
|
public bool TryGetConfig(Language language, out LanguageConfig config)
|
|
{
|
|
return state.Languages.TryGetValue(language, out config);
|
|
}
|
|
|
|
public bool TryGetItem(string key, out IFieldPartitionItem item)
|
|
{
|
|
if (Language.IsValidLanguage(key) && state.Languages.TryGetValue(key, out var value))
|
|
{
|
|
item = value;
|
|
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
item = null;
|
|
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private sealed class State
|
|
{
|
|
public ImmutableDictionary<Language, LanguageConfig> Languages { get; }
|
|
|
|
public LanguageConfig Master { get; }
|
|
|
|
public State(ImmutableDictionary<Language, LanguageConfig> languages, LanguageConfig master)
|
|
{
|
|
foreach (var languageConfig in languages.Values)
|
|
{
|
|
foreach (var fallback in languageConfig.LanguageFallbacks)
|
|
{
|
|
if (!languages.ContainsKey(fallback))
|
|
{
|
|
var message = $"Config for language '{languageConfig.Language.Iso2Code}' contains unsupported fallback language '{fallback.Iso2Code}'";
|
|
|
|
throw new InvalidOperationException(message);
|
|
}
|
|
}
|
|
}
|
|
|
|
Languages = languages;
|
|
|
|
if (master == null)
|
|
{
|
|
throw new InvalidOperationException("Config has no master language.");
|
|
}
|
|
|
|
this.Master = master;
|
|
}
|
|
}
|
|
|
|
public PartitionResolver ToResolver()
|
|
{
|
|
return partitioning =>
|
|
{
|
|
if (partitioning.Equals(Partitioning.Invariant))
|
|
{
|
|
return InvariantPartitioning.Instance;
|
|
}
|
|
|
|
return this;
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|