Skip to content

Commit

Permalink
Add functionality to refresh underlying metadata from a stream.
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Hepburn committed Nov 10, 2021
1 parent 0538c0e commit 99a421c
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 6 deletions.
23 changes: 17 additions & 6 deletions csharp/PhoneNumbers/BuildMetadataFromXml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,27 +80,37 @@ public static PhoneMetadataCollection BuildPhoneMetadataCollection(string name,
=> BuildPhoneMetadata(name, null, liteBuild, specialBuild, isShortNumberMetadata, isAlternateFormatsMetadata, nameSuffix: false);

internal static PhoneMetadataCollection BuildPhoneMetadata(string name, Assembly asm = null,
bool liteBuild = false, bool specialBuild = false, bool isShortNumberMetadata = false, bool isAlternateFormatsMetadata = false,
bool liteBuild = false, bool specialBuild = false, bool isShortNumberMetadata = false,
bool isAlternateFormatsMetadata = false,
bool nameSuffix = true)
{
XDocument document;
#if NETSTANDARD1_3 || PORTABLE
asm ??= typeof(PhoneNumberUtil).GetTypeInfo().Assembly;
#else
asm ??= typeof(PhoneNumberUtil).Assembly;
#endif

if (nameSuffix)
name = asm.GetManifestResourceNames().FirstOrDefault(n => n.EndsWith(name, StringComparison.Ordinal)) ?? throw new ArgumentException(name + " resource not found");
name = asm.GetManifestResourceNames().FirstOrDefault(n => n.EndsWith(name, StringComparison.Ordinal)) ??
throw new ArgumentException(name + " resource not found");

using (var input = asm.GetManifestResourceStream(name))
{
return BuildPhoneMetadataFromStream(input, liteBuild, specialBuild, isShortNumberMetadata,
isAlternateFormatsMetadata);
}
}

internal static PhoneMetadataCollection BuildPhoneMetadataFromStream(Stream metadataStream,
bool liteBuild = false, bool specialBuild = false, bool isShortNumberMetadata = false,
bool isAlternateFormatsMetadata = false)
{
#if NET35
document = XDocument.Load(new XmlTextReader(input));
var document = XDocument.Load(new XmlTextReader(input));
#else
document = XDocument.Load(input);
var document = XDocument.Load(metadataStream);
#endif
}


var metadataCollection = new PhoneMetadataCollection.Builder();
var metadataFilter = GetMetadataFilter(liteBuild, specialBuild);
Expand All @@ -114,6 +124,7 @@ internal static PhoneMetadataCollection BuildPhoneMetadata(string name, Assembly
metadataFilter.FilterMetadata(metadata);
metadataCollection.AddMetadata(metadata);
}

return metadataCollection.Build();
}

Expand Down
53 changes: 53 additions & 0 deletions csharp/PhoneNumbers/PhoneNumberUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,25 @@ internal PhoneNumberUtil(string baseFileLocation, Assembly asm = null, Dictionar
}
regionToMetadataMap.Remove(REGION_CODE_FOR_NON_GEO_ENTITY);
}

internal PhoneNumberUtil(Stream metaDataStream, Dictionary<int, List<string>> countryCallingCodeToRegionCodeMap = null)
{
var phoneMetadata = BuildMetadataFromXml.BuildPhoneMetadataFromStream(metaDataStream);
this.countryCallingCodeToRegionCodeMap = countryCallingCodeToRegionCodeMap ??= BuildMetadataFromXml.BuildCountryCodeToRegionCodeMap(phoneMetadata);

foreach (var regionCodes in countryCallingCodeToRegionCodeMap)
supportedRegions.UnionWith(regionCodes.Value);
supportedRegions.Remove(REGION_CODE_FOR_NON_GEO_ENTITY);
if (countryCallingCodeToRegionCodeMap.TryGetValue(NANPA_COUNTRY_CODE, out var regions))
nanpaRegions.UnionWith(regions);

foreach (var m in phoneMetadata.MetadataList)
{
countryCodeToNonGeographicalMetadataMap[m.CountryCode] = m;
regionToMetadataMap[m.Id] = m;
}
regionToMetadataMap.Remove(REGION_CODE_FOR_NON_GEO_ENTITY);
}

/// <summary>
/// Attempts to extract a possible number from the string passed in. This currently strips all
Expand Down Expand Up @@ -908,6 +927,40 @@ public static PhoneNumberUtil GetInstance(string baseFileLocation,
lock (ThisLock)
return instance ??= new PhoneNumberUtil(baseFileLocation, null, countryCallingCodeToRegionCodeMap);
}

/// <summary>
/// Gets a {@link PhoneNumberUtil} instance to carry out international phone number formatting,
/// parsing, or validation. The instance is loaded with all phone number metadata.
/// The <see cref="PhoneNumberUtil" /> is implemented as a singleton.Therefore, calling getInstance
/// multiple times will only result in one instance being created.
/// </summary>
/// <returns> a PhoneNumberUtil instance</returns>
public static PhoneNumberUtil GetInstance(Stream metadataStream, Dictionary<int, List<string>> countryCallingCodeToRegionCodeMap = null)
{
lock (ThisLock)
return instance ??= new PhoneNumberUtil(metadataStream);
}

/// <summary>
/// Re-instantiates the {@link PhoneNumberUtil} singleton with new metadata.
/// </summary>
/// <param name="metadataStream">Stream of new metadata</param>
public static void RefreshMetadata(Stream metadataStream)
{
lock (ThisLock)
{
var bak = instance;
instance = null;
try
{
instance = new PhoneNumberUtil(metadataStream, null);
}
catch (Exception)
{
instance = bak;
}
}
}

/// <summary>
/// Returns all regions the library has metadata for.
Expand Down

0 comments on commit 99a421c

Please sign in to comment.