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);
            }
        }
Example #2
0
        /// <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);
        }
Example #7
0
        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);
        }
Example #8
0
        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);
        }
Example #9
0
        public bool Reload([NotNull] IList <ProjectFile> sourceFiles, DuplicateKeyHandling duplicateKeyHandling)
        {
            Contract.Requires(sourceFiles != null);

            return(Load(sourceFiles, duplicateKeyHandling));
        }
Example #10
0
        /// <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());
        }
Example #16
0
 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);
        }