/// <summary> /// Exports the resource strings from the Babylon.NET project /// </summary> /// <param name="projectName">Name of the project the resources will be exported from</param> /// <param name="projectLocale">The project invariant locale</param> /// <param name="resourceStrings">The strings to be exported</param> /// <param name="resultDelegate">Callback delegate to provide progress information and storage operation results</param> public void ExportResourceStrings(string projectName, string projectLocale, IReadOnlyCollection <string> localesToExport, ICollection <StringResource> resourceStrings, ResourceStorageOperationResultDelegate resultDelegate) { XliffResourceExporter xliffResourceExporter = new XliffResourceExporter(XliffFileHelpers.GetBaseDirectory(StorageLocation, SolutionPath), projectLocale, localesToExport, resourceStrings, (string xliffFileName) => { resultDelegate?.Invoke(new ResourceStorageOperationResultItem(xliffFileName) { ProjectName = projectName }); }, (XliffFileError fileError) => { resultDelegate?.Invoke(new ResourceStorageOperationResultItem(fileError.XliffFilePath) { ProjectName = projectName, Result = ResourceStorageOperationResult.Error, Message = fileError.Ex.Message }); }); xliffResourceExporter.Export(); }
/// <summary> /// Babylon.NET will call this method when the resource files should be written. /// </summary> /// <param name="projectName">Name of the project whose resources are exported.</param> /// <param name="resourceStrings">A list of resource strings with related translations.</param> /// <param name="resultDelegate">Delegate to return the status of the export.</param> public void ExportResourceStrings(string projectName, ICollection <StringResource> resourceStrings, ResourceStorageOperationResultDelegate resultDelegate) { // We use a dictionary as cache for the resources for each file Dictionary <string, ICollection <StringResource> > fileCache = new Dictionary <string, ICollection <StringResource> >(); // We keep an error list with files that cannot be written to avoid the same error over and over List <string> errorList = new List <string>(); // convert relative storage location into absolute one string baseDirectory = GetBaseDirectory(); // loop over all strings... foreach (var resString in resourceStrings) { // ... and all locales. Babylon.NET uses an empty string as locale for the invariant language. foreach (string locale in resString.GetLocales()) { // assemble file name string filename = Path.Combine(baseDirectory, string.Format("{0}.{1}.xml", resString.StorageLocation, locale)).Replace("..", "."); // if we have this file on the error list skip it if (errorList.Contains(filename)) { continue; } // check if we have the file in our cache if (!fileCache.ContainsKey(filename)) { // load strings from file if file exists if (File.Exists(filename)) { try { var strings = ReadResourceStrings(filename); fileCache.Add(filename, strings); } catch (Exception ex) { if (resultDelegate != null) { ResourceStorageOperationResultItem resultItem = new ResourceStorageOperationResultItem(filename); resultItem.ProjectName = projectName; resultItem.Result = ResourceStorageOperationResult.Error; resultItem.Message = ex.GetBaseException().Message; resultDelegate(resultItem); } errorList.Add(filename); continue; } } else { // create new string list for new file var strings = new List <StringResource>(); fileCache.Add(filename, strings); } } // update the string var stringResources = fileCache[filename]; var s = stringResources.FirstOrDefault(sr => sr.Name == resString.Name); if (s == null) { s = new StringResource(resString.Name, ""); stringResources.Add(s); } s.SetLocaleText(locale, resString.GetLocaleText(locale)); s.Notes = resString.Notes; } } // save all dictionaries in cache foreach (var item in fileCache) { ResourceStorageOperationResultItem resultItem = new ResourceStorageOperationResultItem(item.Key); resultItem.ProjectName = projectName; // get locale from file name string locale = Path.GetExtension(Path.GetFileNameWithoutExtension(item.Key)).TrimStart(new char[] { '.' }); try { WriteResourceStrings(item, locale); // report success resultDelegate?.Invoke(resultItem); } catch (Exception ex) { // report error if (resultDelegate != null) { resultItem.Result = ResourceStorageOperationResult.Error; resultItem.Message = ex.GetBaseException().Message; resultDelegate(resultItem); } } } }
/// <summary> /// Babylon.NET will call this method when the resource files should be written. /// </summary> /// <param name="projectName">Name of the project whose resources are exported.</param> /// <param name="resourceStrings">A list of resource strings with related translations.</param> /// <param name="resultDelegate">Delegate to return the status of the export.</param> public void ExportResourceStrings(string projectName, ICollection <StringResource> resourceStrings, ResourceStorageOperationResultDelegate resultDelegate) { // We use a dictionary as cache for the resources for each file Dictionary <string, Dictionary <string, string> > fileCache = new Dictionary <string, Dictionary <string, string> >(); // We keep an error list with files that cannot be written to avoid the same error over and over List <string> errorList = new List <string>(); // convert relative storage location into absolute one string baseDirectory = GetBaseDirectory(); // loop over all strings... foreach (var resString in resourceStrings) { // ... and all locales. Babylon.NET uses an empty string as locale for the invariant language. foreach (string locale in resString.GetLocales()) { // assemble file name string filename = Path.Combine(baseDirectory, string.Format("{0}.{1}.json", resString.StorageLocation, locale)).Replace("..", "."); // if we have this file on the error list skip it if (errorList.Contains(filename)) { continue; } // check if we have the file in our cache if (!fileCache.ContainsKey(filename)) { // load strings from file if file exists if (File.Exists(filename)) { try { using (StreamReader fileStream = File.OpenText(filename)) { var dict = JsonConvert.DeserializeObject <Dictionary <string, string> >(fileStream.ReadToEnd()); if (dict == null) { dict = new Dictionary <string, string>(); } fileCache.Add(filename, dict); } } catch (Exception ex) { if (resultDelegate != null) { ResourceStorageOperationResultItem resultItem = new ResourceStorageOperationResultItem(filename); resultItem.ProjectName = projectName; resultItem.Result = ResourceStorageOperationResult.Error; resultItem.Message = ex.GetBaseException().Message; resultDelegate(resultItem); } errorList.Add(filename); continue; } } else { // create dictionary for new file var dict = new Dictionary <string, string>(); fileCache.Add(filename, dict); } } // update the string var stringDictionary = fileCache[filename]; stringDictionary[resString.Name] = resString.GetLocaleText(locale); } } // save all dictionaries in cache foreach (var item in fileCache) { ResourceStorageOperationResultItem resultItem = new ResourceStorageOperationResultItem(item.Key); resultItem.ProjectName = projectName; try { // serialize the JSON file using (StreamWriter fileStream = File.CreateText(item.Key)) { fileStream.Write(JsonConvert.SerializeObject(item.Value, Formatting.Indented)); // report success resultDelegate?.Invoke(resultItem); } } catch (Exception ex) { // report error if (resultDelegate != null) { resultItem.Result = ResourceStorageOperationResult.Error; resultItem.Message = ex.GetBaseException().Message; resultDelegate(resultItem); } } } }