/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the priority for the specified id. /// </summary> /// ------------------------------------------------------------------------------------ internal LocalizationPriority GetPriority(string id) { XLiffTransUnit tu = DefaultXliffDocument.GetTransUnitForId(id); if (tu != null) { if (string.IsNullOrEmpty(tu.Priority)) { return(LocalizationPriority.High); } try { return((LocalizationPriority)Enum.Parse(typeof(LocalizationPriority), tu.Priority)); } catch { } } return(LocalizationPriority.NotLocalizable); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the category for the specified id. /// </summary> /// ------------------------------------------------------------------------------------ internal LocalizationCategory GetCategory(string id) { XLiffTransUnit tu = DefaultXliffDocument.GetTransUnitForId(id); if (tu != null) { string category = tu.Category; if (string.IsNullOrEmpty(category)) { return(LocalizationCategory.DontCare); } try { return((LocalizationCategory)Enum.Parse(typeof(LocalizationCategory), category)); } catch { } } return(LocalizationCategory.Other); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the comment for the specified id. /// </summary> /// <remarks> /// The xliff standard allows multiple notes in a trans-unit element. We use one to /// represent the id string (prefacing it with "ID: "). Any other note is liable to be /// considered the "comment" if it exists. /// </remarks> /// ------------------------------------------------------------------------------------ public string GetComment(string id) { XLiffTransUnit tu = DefaultXliffDocument.GetTransUnitForId(id); return(tu == null ? null : tu.GetComment()); }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets the group for the specified id. /// </summary> /// ------------------------------------------------------------------------------------ internal string GetGroup(string id) { XLiffTransUnit tu = DefaultXliffDocument.GetTransUnitForId(id); return(tu == null ? null : tu.Group); }
/// <summary> /// Load the language data, if any, from the unloaded xliff file associated with langId /// (or its primary language, if different) and update MapToExistingLanguage according /// to what we find. /// Use only from TryGetDocument. Should hold LazyLoadLock. /// </summary> private void LoadXliffAndUpdateExistingLanguageMap(string langId) { if (!_unloadedXliffDocuments.TryRemove(langId, out string file)) { // Often an xliff in a plain lang folder (like "es") contains // a target-language that is more specific (like "es-ES"). // If we're asked to try to load the xliff for es-ES and don't find one, // Try loading the one for es. var pieces = langId.Split('-'); if (pieces.Length <= 1) { return; } if (!_unloadedXliffDocuments.TryRemove(pieces[0], out file)) { return; } } var xliffDoc = XLiffDocument.Read(file); // This might be different, typically more specific, than the name we deduced from the file path. var targetLang = xliffDoc.File.TargetLang; // Now we have some maintenance to do on MapToExistingLanguage, which does not yet contain data // about this file. It is definitely the one to use for targetLanguage. LocalizationManagerInternal <XLiffDocument> .MapToExistingLanguage[targetLang] = targetLang; var piecesOfTargetLang = targetLang.Split('-'); if (piecesOfTargetLang.Length > 1) { var rootLangId = piecesOfTargetLang[0]; // If we don't already have an xliff to use for the root language, tell it to use this one. // For example, suppose we have file in the es folder whose target-language is es-ES. // We probably want MapToExistingLanguage to have es -> es-ES (as well as es-ES -> es-ES). // But we have to be careful. It's also possible that we have both an es folder (where target-language is es) // AND an es-ES folder where targetLanguage is es-ES. We might load the plain es one either first or second. // In those cases, we don't want to get es -> es-ES. In case we haven't already loaded it, // we check that the root language isn't still waiting to load (in _unlodedXliffDocuments); // in case we already did, we make sure there isn't already a value under that key in MapToExistingLanguage. // (This also means that, in case we have e.g. es-ES and also es-BR but no plain es, one of the two // wins out as the one to use for es, and doesn't change later.) if (!LocalizationManagerInternal <XLiffDocument> .MapToExistingLanguage.TryGetValue(rootLangId, out _) && !_unloadedXliffDocuments.TryGetValue(rootLangId, out _)) { LocalizationManagerInternal <XLiffDocument> .MapToExistingLanguage[rootLangId] = targetLang; } } XliffDocuments.TryAdd(targetLang, xliffDoc); var defunctUnits = new List <XLiffTransUnit>(); foreach (var tu in xliffDoc.File.Body.TransUnitsUnordered.ToList()) // need a list here because we may modify it while enumerating { // This block attempts to find 'orphans', that is, localizations that have been done using an obsolete ID. // We assume the default language Xliff has only current IDs, and therefore don't look for orphans in that case. // This guards against cases such as recently occurred in Bloom, where a dynamic ID EditTab.AddPageDialog.Title // was regarded as an obsolete id for PublishTab.Upload.Title if (langId != LocalizationManager.kDefaultLang && DefaultXliffDocument.GetTransUnitForId(tu.Id) == null && !tu.Id.EndsWith(kToolTipSuffix) && !tu.Id.EndsWith(kShortcutSuffix)) { //if we couldn't find it, maybe the id just changed and then if so re-id it. var movedUnit = DefaultXliffDocument.GetTransUnitForOrphan(tu, xliffDoc.File.Body); if (movedUnit == null) { // with dynamic strings, by definition we won't find them during a static code scan if (!tu.Dynamic) { defunctUnits.Add(tu); xliffDoc.IsDirty = true; IsDirty = true; } } else { if (xliffDoc.File.Body.TranslationsById.ContainsKey(tu.Id)) { // adjust the document's internal cache xliffDoc.File.Body.TranslationsById[movedUnit.Id] = xliffDoc.File.Body.TranslationsById[tu.Id]; xliffDoc.File.Body.TranslationsById.TryRemove(tu.Id, out _); } // Note: this function is used inside a lock, so we don't have to worry // about other threads interfering here. xliffDoc.File.Body.RemoveTransUnit(tu); tu.Id = movedUnit.Id; xliffDoc.File.Body.AddTransUnit(tu); xliffDoc.IsDirty = true; IsDirty = true; } } } // Now we can delete any invalid XLiffTransUnit objects from this document. foreach (var tuBad in defunctUnits) { xliffDoc.File.Body.RemoveTransUnit(tuBad); } }