private void UpdateNodes(DuplicateKeyHandling duplicateKeyHandling) { var data = DocumentRoot.Elements(_dataNodeName); var elements = data .Where(IsStringType) .Select(item => new Node(this, item)) .Where(item => !item.Key.StartsWith(WinFormsMemberNamePrefix, StringComparison.OrdinalIgnoreCase)) .ToArray(); if (duplicateKeyHandling == DuplicateKeyHandling.Rename) { MakeKeysValid(elements); } else { if (elements.Any(item => string.IsNullOrEmpty(item.Key))) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.EmptyKeysError, ProjectFile.FilePath)); } } try { _nodes = elements.ToDictionary(item => item.Key); } catch (ArgumentException ex) { var duplicateKeys = string.Join(@", ", elements.GroupBy(item => item.Key).Where(group => group.Count() > 1).Select(group => Quote + group.Key + Quote)); throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.DuplicateKeyError, ProjectFile.FilePath, duplicateKeys), ex); } }
/// <summary> /// Loads all resources from the specified project files. /// </summary> /// <param name="allSourceFiles">All resource x files.</param> /// <param name="duplicateKeyHandling">The duplicate key handling mode.</param> private bool Load([NotNull] IList <ProjectFile> allSourceFiles, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(allSourceFiles != null); var resourceFilesByDirectory = allSourceFiles .Where(file => file.IsResourceFile()) .GroupBy(file => file.GetBaseDirectory()); return(InternalLoad(resourceFilesByDirectory, duplicateKeyHandling)); }
/// <summary> /// Adds the language represented by the specified file. /// </summary> /// <param name="file">The file.</param> /// <param name="duplicateKeyHandling">How to handle duplicate keys.</param> public void AddLanguage([NotNull] ProjectFile file, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(file != null); var cultureKey = file.GetCultureKey(); var resourceLanguage = new ResourceLanguage(this, cultureKey, file, duplicateKeyHandling); _languages.Add(cultureKey, resourceLanguage); _resourceTableEntries.ForEach(entry => entry.Refresh()); Container.LanguageAdded(resourceLanguage.CultureKey); }
public void SortNodes(StringComparison stringComparison, DuplicateKeyHandling duplicateKeyHandling) { if (!SortDocument(stringComparison)) { return; } UpdateNodes(duplicateKeyHandling); Container.OnItemOrderChanged(this); ProjectFile.Changed(_document, true); Save(); }
internal bool Update([NotNull] ICollection <ProjectFile> files, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(files != null); Contract.Requires(files.Any()); if (!MergeItems(_languages, GetResourceLanguages(files, duplicateKeyHandling))) { return(false); // nothing has changed, no need to continue } _neutralProjectFile = files.FirstOrDefault(file => file.GetCultureKey() == CultureKey.Neutral); var unmatchedTableEntries = _resourceTableEntries.ToList(); var keys = _languages.Values .SelectMany(language => language.ResourceKeys) .Distinct() .ToArray(); var index = 0; foreach (var key in keys) { Contract.Assume(!string.IsNullOrEmpty(key)); var existingEntry = _resourceTableEntries.FirstOrDefault(entry => entry.Key == key); if (existingEntry != null) { Contract.Assume(_languages.Any()); existingEntry.Update(index, _languages); unmatchedTableEntries.Remove(existingEntry); } else { Contract.Assume(_languages.Any()); _resourceTableEntries.Add(new ResourceTableEntry(this, key, index, _languages)); } index += 1; } _resourceTableEntries.RemoveRange(unmatchedTableEntries); OnPropertyChanged(nameof(NeutralProjectFile)); return(true); }
private IDictionary <CultureKey, ResourceLanguage> GetResourceLanguages([NotNull] IEnumerable <ProjectFile> files, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(files != null); Contract.Requires(files.Any()); Contract.Ensures(Contract.Result <IDictionary <CultureKey, ResourceLanguage> >() != null); Contract.Ensures(Contract.Result <IDictionary <CultureKey, ResourceLanguage> >().Any()); var languageQuery = from file in files let cultureKey = file.GetCultureKey() orderby cultureKey select new ResourceLanguage(this, cultureKey, file, duplicateKeyHandling); var languages = languageQuery.ToDictionary(language => language.CultureKey); Contract.Assume(languages.Any()); return(languages); }
private bool LoadEntities([NotNull] IEnumerable <IGrouping <string, ProjectFile> > fileNamesByDirectory, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(fileNamesByDirectory != null); var hasChanged = false; var unmatchedEntities = _resourceEntities.ToList(); foreach (var directory in fileNamesByDirectory) { Contract.Assume(directory != null); var directoryName = directory.Key; Contract.Assume(!string.IsNullOrEmpty(directoryName)); var filesByBaseName = directory.GroupBy(file => file.GetBaseName()); foreach (var files in filesByBaseName) { if ((files == null) || !files.Any()) { continue; } var baseName = files.Key; Contract.Assume(!string.IsNullOrEmpty(baseName)); var filesByProject = files.GroupBy(file => file.ProjectName); foreach (var item in filesByProject) { Contract.Assume(item != null); var projectName = item.Key; var projectFiles = item.ToArray(); if (string.IsNullOrEmpty(projectName) || !projectFiles.Any()) { continue; } var existingEntity = _resourceEntities.FirstOrDefault(entity => entity.EqualsAll(projectName, baseName, directoryName)); if (existingEntity != null) { if (existingEntity.Update(projectFiles, duplicateKeyHandling)) { hasChanged = true; } unmatchedEntities.Remove(existingEntity); } else { _resourceEntities.Add(new ResourceEntity(this, projectName, baseName, directoryName, projectFiles, duplicateKeyHandling)); hasChanged = true; } } } } _resourceEntities.RemoveRange(unmatchedEntities); hasChanged |= unmatchedEntities.Any(); return(hasChanged); }
private bool InternalLoad([NotNull] IEnumerable <IGrouping <string, ProjectFile> > resourceFilesByDirectory, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(resourceFilesByDirectory != null); if (!LoadEntities(resourceFilesByDirectory, duplicateKeyHandling)) { return(false); // nothing has changed, no need to continue } if (!string.IsNullOrEmpty(_snapshot)) { _resourceEntities.LoadSnapshot(_snapshot); } var cultureKeys = _resourceEntities .SelectMany(entity => entity.Languages) .Select(lang => lang.CultureKey) .Distinct() .OrderBy(item => item.Culture?.DisplayName) .ToArray(); _cultureKeys.SynchronizeWith(cultureKeys); OnLoaded(); return(true); }
public bool Reload([NotNull] IList <ProjectFile> sourceFiles, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(sourceFiles != null); return(Load(sourceFiles, duplicateKeyHandling)); }
/// <summary> /// Initializes a new instance of the <see cref="ResourceLanguage" /> class. /// </summary> /// <param name="container">The containing resource entity.</param> /// <param name="cultureKey">The culture key.</param> /// <param name="file">The .resx file having all the localization.</param> /// <param name="duplicateKeyHandling">How to handle duplicate keys.</param> /// <exception cref="System.InvalidOperationException"> /// </exception> internal ResourceLanguage([NotNull] ResourceEntity container, [NotNull] CultureKey cultureKey, [NotNull] ProjectFile file, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(container != null); Contract.Requires(cultureKey != null); Contract.Requires(file != null); _container = container; _cultureKey = cultureKey; _file = file; try { _document = file.Load(); _documentRoot = _document.Root; } catch (XmlException ex) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidResourceFileError, file.FilePath), ex); } if (_documentRoot == null) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidResourceFileError, file.FilePath)); } var defaultNamespace = _documentRoot.GetDefaultNamespace(); _dataNodeName = defaultNamespace.GetName(@"data"); _valueNodeName = defaultNamespace.GetName(@"value"); _commentNodeName = defaultNamespace.GetName(@"comment"); UpdateNodes(file, duplicateKeyHandling); }
internal bool Update(ICollection <ProjectFile> files, CultureInfo neutralResourcesLanguage, DuplicateKeyHandling duplicateKeyHandling) { if (!MergeItems(_languages, GetResourceLanguages(files, neutralResourcesLanguage, duplicateKeyHandling))) { return(false); // nothing has changed, no need to continue } var neutralProjectFile = files.FirstOrDefault(file => file.GetCultureKey(neutralResourcesLanguage) == CultureKey.Neutral); var unmatchedTableEntries = _resourceTableEntries.ToList(); var keys = _languages.Values .SelectMany(language => language.ResourceKeys) .Distinct() .ToArray(); var index = 0; foreach (var key in keys) { var existingEntry = _resourceTableEntries.FirstOrDefault(entry => entry.Key == key); if (existingEntry != null) { existingEntry.Update(index); unmatchedTableEntries.Remove(existingEntry); } else { _resourceTableEntries.Add(new ResourceTableEntry(this, key, index, _languages)); } index += 1; } _resourceTableEntries.RemoveRange(unmatchedTableEntries); NeutralProjectFile = neutralProjectFile; return(true); }
private IDictionary <CultureKey, ResourceLanguage> GetResourceLanguages(IEnumerable <ProjectFile> files, CultureInfo neutralResourcesLanguage, DuplicateKeyHandling duplicateKeyHandling) { var languageQuery = from file in files let cultureKey = file.GetCultureKey(neutralResourcesLanguage) orderby cultureKey select new ResourceLanguage(this, cultureKey, file, duplicateKeyHandling); var languages = languageQuery.ToDictionary(language => language.CultureKey); return(languages); }
internal ResourceEntity(ResourceManager container, string projectName, string baseName, string directoryName, ICollection <ProjectFile> files, CultureInfo neutralResourcesLanguage, DuplicateKeyHandling duplicateKeyHandling) { Container = container; ProjectName = projectName; BaseName = baseName; DirectoryName = directoryName; _languages = GetResourceLanguages(files, neutralResourcesLanguage, duplicateKeyHandling); RelativePath = GetRelativePath(files); DisplayName = projectName + @" - " + RelativePath + baseName; NeutralProjectFile = files.FirstOrDefault(file => file.GetCultureKey(neutralResourcesLanguage) == CultureKey.Neutral); var entriesQuery = _languages.Values .SelectMany(language => language.ResourceKeys) .Distinct() .Select((key, index) => new ResourceTableEntry(this, key, index, _languages)); _resourceTableEntries = new ObservableCollection <ResourceTableEntry>(entriesQuery); Entries = new ReadOnlyObservableCollection <ResourceTableEntry>(_resourceTableEntries); }
/// <summary> /// Initializes a new instance of the <see cref="ResourceLanguage" /> class. /// </summary> /// <param name="container">The containing resource entity.</param> /// <param name="cultureKey">The culture key.</param> /// <param name="file">The .resx file having all the localization.</param> /// <param name="duplicateKeyHandling">The duplicate key handling.</param> /// <exception cref="InvalidOperationException"> /// </exception> /// <exception cref="System.InvalidOperationException"></exception> internal ResourceLanguage(ResourceEntity container, CultureKey cultureKey, ProjectFile file, DuplicateKeyHandling duplicateKeyHandling) { Container = container; CultureKey = cultureKey; ProjectFile = file; _configuration = container.Container.Configuration; try { _document = file.Load(); } catch (XmlException ex) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidResourceFileError, file.FilePath), ex); } if (DocumentRoot == null) { throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.InvalidResourceFileError, file.FilePath)); } var defaultNamespace = DocumentRoot.GetDefaultNamespace(); _dataNodeName = defaultNamespace.GetName(@"data"); _valueNodeName = defaultNamespace.GetName(@"value"); _commentNodeName = defaultNamespace.GetName(@"comment"); UpdateNodes(duplicateKeyHandling); }
internal ResourceEntity([NotNull] ResourceManager container, [NotNull] string projectName, [NotNull] string baseName, [NotNull] string directoryName, [NotNull] ICollection <ProjectFile> files, DuplicateKeyHandling duplicateKeyHandling) { Contract.Requires(container != null); Contract.Requires(!string.IsNullOrEmpty(projectName)); Contract.Requires(!string.IsNullOrEmpty(baseName)); Contract.Requires(!string.IsNullOrEmpty(directoryName)); Contract.Requires(files != null); Contract.Requires(files.Any()); _container = container; _projectName = projectName; _baseName = baseName; _directoryName = directoryName; _languages = GetResourceLanguages(files, duplicateKeyHandling); _relativePath = GetRelativePath(files); _displayName = projectName + @" - " + _relativePath + baseName; _sortKey = string.Concat(@" - ", _displayName, _directoryName); _neutralProjectFile = files.FirstOrDefault(file => file.GetCultureKey() == CultureKey.Neutral); var entriesQuery = _languages.Values .SelectMany(language => language.ResourceKeys) .Distinct() .Select((key, index) => new ResourceTableEntry(this, key, index, _languages)); _resourceTableEntries = new ObservableCollection <ResourceTableEntry>(entriesQuery); _readOnlyResourceTableEntries = new ReadOnlyObservableCollection <ResourceTableEntry>(_resourceTableEntries); Contract.Assume(_languages.Any()); }
public bool Reload(DuplicateKeyHandling duplicateKeyHandling) { return(Reload(_sourceFilesProvider.SourceFiles, duplicateKeyHandling)); }
internal bool Update(ICollection <ProjectFile> files, CultureInfo neutralResourcesLanguage, DuplicateKeyHandling duplicateKeyHandling) { NeutralResourcesLanguage = neutralResourcesLanguage; if (!MergeItems(GetResourceLanguages(files, neutralResourcesLanguage, duplicateKeyHandling))) { return(false); // nothing has changed, no need to continue } var neutralProjectFile = files.FirstOrDefault(file => file.GetCultureKey(neutralResourcesLanguage) == CultureKey.Neutral); UpdateResourceTableEntries(); NeutralProjectFile = neutralProjectFile; return(true); }