Beispiel #1
0
        /// <summary>
        /// May only be called from constructor. Not thread-safe.
        /// </summary>
        private void MergeXliffFilesIntoCache(IEnumerable <string> xliffFiles)
        {
            DefaultXliffDocument = XLiffDocument.Read(OwningManager.DefaultStringFilePath);             // read the generated file
            // It's possible (I think when there is no customizable Xliff, as on first install, but the version in the installed Xliff
            // is out of date with the app) that we don't have all the info from the installed Xliff in the customizable one.
            // We want to make sure that (a) any new dynamic strings in the installed one are considered valid by default
            // (b) any newly obsolete IDs are noted.
            if (File.Exists(OwningManager.DefaultInstalledStringFilePath))
            {
                if (!XLiffLocalizationManager.ScanningForCurrentStrings)
                {
                    var defaultInstalledXliffDoc = XLiffDocument.Read(OwningManager.DefaultInstalledStringFilePath);
                    foreach (var tu in defaultInstalledXliffDoc.File.Body.TransUnitsUnordered)
                    {
                        DefaultXliffDocument.File.Body.AddTransUnitOrVariantFromExisting(tu,
                                                                                         LocalizationManager.kDefaultLang);
                    }
                }
            }

            XliffDocuments.TryAdd(LocalizationManager.kDefaultLang, DefaultXliffDocument);
            // Map the default language onto itself.
            LocalizationManagerInternal <XLiffDocument> .MapToExistingLanguage[LocalizationManager.kDefaultLang] =
                LocalizationManager.kDefaultLang;

            foreach (var file in xliffFiles)
            {
                var langId = XLiffLocalizationManager.GetLangIdFromXliffFileName(file);
                Debug.Assert(!string.IsNullOrEmpty(langId));
                Debug.Assert(langId != LocalizationManager.kDefaultLang);
                _unloadedXliffDocuments[langId] = file;
            }
        }
        public void MergeXliffDocuments_WorksAsExpected()
        {
            var oldDoc = CreateTestDocument();
            var newDoc = CreateTestDocument();

            AdjustDocumentForTestingMerge(newDoc);

            var mergedDoc = XLiffLocalizationManager.MergeXliffDocuments(newDoc, oldDoc, true);

            Assert.IsNotNull(mergedDoc);
            Assert.That(5, Is.EqualTo(oldDoc.File.Body.TransUnits.Count));
            Assert.That(6, Is.EqualTo(newDoc.File.Body.TransUnits.Count));
            Assert.That(8, Is.EqualTo(mergedDoc.File.Body.TransUnits.Count));

            var tu = mergedDoc.GetTransUnitForId("This.test");

            CheckMergedTransUnit(tu, "This is a test.",
                                 new[] { "ID: This.test", "This is only a test" }, false);

            tu = mergedDoc.GetTransUnitForId("That.test");
            CheckMergedTransUnit(tu, "That was a test.",
                                 new[] {
                "ID: That.test",
                "That is hard to explain, but a literal rendition is okay.",
                "Not found in static scan of compiled code (version 3.1.4)"
            }, false);

            tu = mergedDoc.GetTransUnitForId("What.test");
            CheckMergedTransUnit(tu, "What is a good test?", new[] {
                "ID: What.test",
                "[OLD NOTE] Whatever you say...", "[OLD NOTE] This should be a question.",
                "OLD TEXT (before 1.0): What are good test.",
                "OLD TEXT (before 3.1.4): What is good test."
            }, true);

            tu = mergedDoc.GetTransUnitForId("What.this");
            CheckMergedTransUnit(tu, "What is this nonsense?",
                                 new[] {
                "ID: What.this",
                "Not dynamic: found in static scan of compiled code (version 3.1.4)"
            }, false);
            Assert.IsNotNull(tu);

            tu = mergedDoc.GetTransUnitForId("This.new1");
            CheckMergedTransUnit(tu, "This is a new test.",
                                 new[] { "ID: This.new1", "This is still only a test" }, false);

            tu = mergedDoc.GetTransUnitForId("That.new2");
            CheckMergedTransUnit(tu, "That was an old test.",
                                 new[] { "ID: That.new2", "That should be easy to translate." }, false);

            tu = mergedDoc.GetTransUnitForId("What.new3");
            CheckMergedTransUnit(tu, "What's up, doc?", new[] { "ID: What.new3" }, true);

            tu = mergedDoc.GetTransUnitForId("How.now");
            CheckMergedTransUnit(tu, "How now brown cow",
                                 new[] {
                "ID: How.now", "Not found when running compiled program (version 3.1.4)"
            }, true);
        }
Beispiel #3
0
        static void Main(string[] args)
        {
            // Parse and check the command line arguments.
            if (!ParseOptions(args))
            {
                Usage();
                return;
            }

            LocalizationManager.TranslationMemoryKind = TranslationMemory.XLiff;

            // Load the input assemblies so that they can be scanned.
            List <Assembly> assemblies = new List <Assembly>();

            foreach (var file in _assemblyFiles)
            {
                var asm = Assembly.LoadFile(file);
                if (asm != null)
                {
                    assemblies.Add(asm);
                }
            }

            // Scan the input assemblies for localizable strings.
            var extractor = new StringExtractor <XLiffDocument> {
                ExternalAssembliesToScan = assemblies.ToArray()
            };
            var localizedStrings = extractor.DoExtractingWork(_namespaces.ToArray(), null);

            // The arguments to this constructor don't really matter much as they're used internally by
            // L10NSharp for reasons that may not percolate out to xliff.  We just need a LocalizationManagerInternal
            // to feed into the constructor the LocalizedStringCache that does some heavy lifting for us in
            // creating the XliffDocument from the newly extracted localized strings.
            var lm          = new XLiffLocalizationManager(_fileOriginal, _fileOriginal, _fileProductVersion);
            var stringCache = new XLiffLocalizedStringCache(lm, false);

            foreach (var locInfo in localizedStrings)
            {
                stringCache.UpdateLocalizedInfo(locInfo);
            }

            // Get the newly loaded static strings (in newDoc) and the baseline XLIFF (in baseDoc).
            var newDoc  = stringCache.XliffDocuments[kDefaultLangId];
            var baseDoc = LoadBaselineAndCompare(newDoc);

            // Save the results to the output file, merging in data from the baseline XLIFF if one was specified.
            var xliffOutput = XLiffLocalizationManager.MergeXliffDocuments(newDoc, baseDoc, _verbose);

            xliffOutput.File.SourceLang               = kDefaultLangId;
            xliffOutput.File.ProductVersion           = !string.IsNullOrEmpty(_fileProductVersion) ? _fileProductVersion : newDoc.File.ProductVersion;
            xliffOutput.File.HardLineBreakReplacement = kDefaultNewlineReplacement;
            xliffOutput.File.AmpersandReplacement     = kDefaultAmpersandReplacement;
            xliffOutput.File.Original = _fileOriginal;
            xliffOutput.File.DataType = !string.IsNullOrEmpty(_fileDatatype) ? _fileDatatype : newDoc.File.DataType;
            xliffOutput.Save(_xliffOutputFilename);
        }
Beispiel #4
0
        /// ------------------------------------------------------------------------------------
        /// <summary>
        /// Now that L10NSharp creates all writable Xliff/Tmx files under LocalApplicationData
        /// instead of the common/shared AppData folder, applications can use this method to
        /// purge old Xliff/Tmx files.</summary>
        /// <param name="appId">ID of the application used for creating the Xliff/Tmx files
        /// (typically the same ID passed as the 2nd parameter to LocalizationManagerInternal.Create).
        /// </param>
        /// <param name="directoryOfWritableTranslationFiles">Folder from which to delete
        /// Xliff/Tmx files.</param>
        /// <param name="directoryOfInstalledTranslationFiles">Used to limit file deletion to only
        /// include copies of the installed Xliff/Tmx files (plus the generated default file). If
        /// this is <c>null</c>, then all Xliff/Tmx files for the given appID will be deleted from
        /// <paramref name="directoryOfWritableTranslationFiles"/></param>
        /// ------------------------------------------------------------------------------------
        public static void DeleteOldTranslationFiles(string appId,
                                                     string directoryOfWritableTranslationFiles, string directoryOfInstalledTranslationFiles)
        {
            switch (TranslationMemoryKind)
            {
            case TranslationMemory.XLiff:
                XLiffLocalizationManager.DeleteOldXliffFiles(appId,
                                                             directoryOfWritableTranslationFiles,
                                                             directoryOfInstalledTranslationFiles);
                break;

            default:
                TMXLocalizationManager.DeleteOldTmxFiles(appId,
                                                         directoryOfWritableTranslationFiles,
                                                         directoryOfInstalledTranslationFiles);
                break;
            }
        }
Beispiel #5
0
        static void Main(string[] args)
        {
            // Parse and check the command line arguments.
            if (!ParseOptions(args))
            {
                Usage();
                return;
            }

            LocalizationManager.TranslationMemoryKind = TranslationMemory.XLiff;

            // Load the input assemblies so that they can be scanned.
            List <Assembly> assemblies = new List <Assembly>();

            List <string> assemblyPaths = new List <string>();

            if (_glob)
            {
                foreach (var glob in _assemblyFiles)
                {
                    assemblyPaths.AddRange(Directory.GetFiles(Path.GetDirectoryName(glob), Path.GetFileName(glob)));
                }
            }
            else
            {
                assemblyPaths = _assemblyFiles;
            }
            foreach (var file in assemblyPaths)
            {
                // Using LoadFrom to make sure we pick up other assemblies in the same directory so we don't fail
                // to load because of 'missing' dependencies
                var asm = Assembly.LoadFrom(file);
                assemblies.Add(asm);

                for (var index = 0; index < _additionalLocalizationMethodNames.Count; index++)
                {
                    var methodNameSpec = _additionalLocalizationMethodNames[index];
                    try
                    {
                        var type = asm.GetType(methodNameSpec.Item1 + "." + methodNameSpec.Item2);
                        if (type == null)
                        {
                            continue;
                        }
                        _additionalLocalizationMethods.AddRange(type
                                                                .GetMethods(BindingFlags.Static | BindingFlags.Public)
                                                                .Where(m => m.Name == methodNameSpec.Item3));

                        if (_verbose)
                        {
                            Console.WriteLine($"Method {methodNameSpec.Item2}.{methodNameSpec.Item3} in {asm.GetName().FullName} will be treated as a localization method.");
                        }
                        _additionalLocalizationMethodNames.RemoveAt(index--);
                    }
                    catch (Exception e)
                    {
                        if (_verbose)
                        {
                            Console.WriteLine("Error using reflection on {asm.GetName().FullName} to get type {methodNameSpec.Item2} or method {methodNameSpec.Item3}:" + e.Message);
                        }
                    }
                }
            }
            if (_verbose && _additionalLocalizationMethodNames.Any())
            {
                Console.WriteLine("Failed to find the following additional localization methods:");
                foreach (var methodNameSpec in _additionalLocalizationMethodNames)
                {
                    Console.WriteLine($"{methodNameSpec.Item1}.{methodNameSpec.Item2}.{methodNameSpec.Item3}");
                }
            }

            // Scan the input assemblies for localizable strings.
            var extractor = new StringExtractor <XLiffDocument> {
                ExternalAssembliesToScan = assemblies.ToArray()
            };

            extractor.OutputErrorsToConsole = _verbose;
            var localizedStrings = extractor.DoExtractingWork(_additionalLocalizationMethods, _namespaces.ToArray(), null);

            // The arguments to this constructor don't really matter much as they're used internally by
            // L10NSharp for reasons that may not percolate out to xliff. We just need a LocalizationManagerInternal
            // to feed into the constructor the LocalizedStringCache that does some heavy lifting for us in
            // creating the XliffDocument from the newly extracted localized strings.
            var lm          = new XLiffLocalizationManager(_fileOriginal, _fileOriginal, _fileProductVersion);
            var stringCache = new XLiffLocalizedStringCache(lm, false);

            foreach (var locInfo in localizedStrings)
            {
                stringCache.UpdateLocalizedInfo(locInfo);
            }

            // Get the newly loaded static strings (in newDoc) and the baseline XLIFF (in baseDoc).
            var newDoc  = stringCache.GetDocument(kDefaultLangId);
            var baseDoc = LoadBaselineAndCompare(newDoc);

            // Save the results to the output file, merging in data from the baseline XLIFF if one was specified.
            var xliffOutput = XLiffLocalizationManager.MergeXliffDocuments(newDoc, baseDoc, _verbose);

            xliffOutput.File.SourceLang               = kDefaultLangId;
            xliffOutput.File.ProductVersion           = !string.IsNullOrEmpty(_fileProductVersion) ? _fileProductVersion : newDoc.File.ProductVersion;
            xliffOutput.File.HardLineBreakReplacement = kDefaultNewlineReplacement;
            xliffOutput.File.AmpersandReplacement     = kDefaultAmpersandReplacement;
            xliffOutput.File.Original = _fileOriginal;
            xliffOutput.File.DataType = !string.IsNullOrEmpty(_fileDatatype) ? _fileDatatype : newDoc.File.DataType;
            xliffOutput.Save(_xliffOutputFilename);
        }
Beispiel #6
0
 /// ------------------------------------------------------------------------------------
 /// <summary>
 /// Now that L10NSharp creates all writable Xliff files under LocalApplicationData
 /// instead of the common/shared AppData folder, applications can use this method to
 /// purge old Xliff files.</summary>
 /// <param name="appId">ID of the application used for creating the Xliff files (typically
 /// the same ID passed as the 2nd parameter to LocalizationManagerInternal.Create).</param>
 /// <param name="directoryOfWritableXliffFiles">Folder from which to delete Xliff files.
 /// </param>
 /// <param name="directoryOfInstalledXliffFiles">Used to limit file deletion to only
 /// include copies of the installed Xliff files (plus the generated default file). If this
 /// is <c>null</c>, then all Xliff files for the given appID will be deleted from
 /// <paramref name="directoryOfWritableXliffFiles"/></param>
 /// ------------------------------------------------------------------------------------
 public static void DeleteOldXliffFiles(string appId, string directoryOfWritableXliffFiles,
                                        string directoryOfInstalledXliffFiles)
 {
     XLiffLocalizationManager.DeleteOldXliffFiles(appId, directoryOfWritableXliffFiles,
                                                  directoryOfInstalledXliffFiles);
 }