| using Lucene.Net.Support; |
| using Lucene.Net.Util; |
| using System; |
| using System.Collections.Generic; |
| using System.Globalization; |
| using System.Reflection; |
| using System.Resources; |
| |
| namespace Lucene.Net.QueryParsers.Flexible.Messages |
| { |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /// <summary> |
| /// MessageBundles classes extend this class, to implement a bundle. |
| /// |
| /// For Native Language Support (NLS), system of software internationalization. |
| /// |
| /// This interface is similar to the NLS class in eclipse.osgi.util.NLS class - |
| /// initializeMessages() method resets the values of all static strings, should |
| /// only be called by classes that extend from NLS (see TestMessages.java for |
| /// reference) - performs validation of all message in a bundle, at class load |
| /// time - performs per message validation at runtime - see NLSTest.java for |
| /// usage reference |
| /// |
| /// MessageBundle classes may subclass this type. |
| /// </summary> |
| public abstract class NLS // LUCENENET specific: CA1052 Static holder types should be Static or NotInheritable |
| { |
| /// <summary> |
| /// LUCENENET specific factory reference to inject instances of <see cref="ResourceManager"/> |
| /// into this class. |
| /// </summary> |
| private static IResourceManagerFactory resourceManagerFactory = new BundleResourceManagerFactory(); |
| private static readonly IDictionary<string, Type> bundles = new Dictionary<string, Type>(0); // LUCENENET: marked readonly |
| |
| protected NLS() |
| { |
| // Do not instantiate |
| } |
| |
| /// <summary> |
| /// Gets the static <see cref="IResourceManagerFactory"/> instance responsible |
| /// for creating <see cref="ResourceManager"/> instances in this class. LUCENENET specific. |
| /// </summary> |
| // LUCENENET NOTE: Don't make this into a property in case we need to make it into an extension method |
| // in a centralized DI configuration builder. |
| public static IResourceManagerFactory GetResourceManagerFactory() |
| { |
| return resourceManagerFactory; |
| } |
| |
| /// <summary> |
| /// Sets the <see cref="IResourceManagerFactory"/> used to create instances of <see cref="ResourceManager"/> |
| /// for retrieving localized resources. Defaults to <see cref="BundleResourceManagerFactory"/> if not set. LUCENENET specific. |
| /// </summary> |
| /// <param name="resourceManagerFactory">The <see cref="IResourceManagerFactory"/> instance. Cannot be <c>null</c>.</param> |
| // LUCENENET NOTE: Don't make this into a property in case we need to make it into an extension method |
| // in a centralized DI configuration builder. |
| public static void SetResourceManagerFactory(IResourceManagerFactory resourceManagerFactory) |
| { |
| NLS.resourceManagerFactory = resourceManagerFactory ?? throw new ArgumentNullException(nameof(resourceManagerFactory)); |
| } |
| |
| public static string GetLocalizedMessage(string key) |
| { |
| return GetLocalizedMessage(key, CultureInfo.InvariantCulture); |
| } |
| |
| public static string GetLocalizedMessage(string key, CultureInfo locale) |
| { |
| string message = GetResourceBundleObject(key, locale); |
| if (message == null) |
| { |
| return "Message with key:" + key + " and locale: " + locale |
| + " not found."; |
| } |
| return message; |
| } |
| |
| public static string GetLocalizedMessage(string key, CultureInfo locale, |
| params object[] args) |
| { |
| string str = GetLocalizedMessage(key, locale); |
| |
| if (args.Length > 0) |
| { |
| str = string.Format(locale, str, args); |
| } |
| |
| return str; |
| } |
| |
| public static string GetLocalizedMessage(string key, params object[] args) |
| { |
| return GetLocalizedMessage(key, CultureInfo.CurrentUICulture, args); |
| } |
| |
| /// <summary> |
| /// Initialize a given class with the message bundle Keys Should be called from |
| /// a class that extends NLS in a static block at class load time. |
| /// </summary> |
| /// <param name="bundleName">Property file with that contains the message bundle</param> |
| /// <param name="clazz">where constants will reside</param> |
| protected static void InitializeMessages(string bundleName, Type clazz) |
| { |
| try |
| { |
| Load(clazz); |
| if (!bundles.ContainsKey(bundleName)) |
| bundles[bundleName] = clazz; |
| } |
| catch (Exception) // LUCENENET: IDE0059: Remove unnecessary value assignment |
| { |
| // ignore all errors and exceptions |
| // because this function is supposed to be called at class load time. |
| } |
| } |
| |
| private static string GetResourceBundleObject(string messageKey, CultureInfo locale) |
| { |
| // slow resource checking |
| // need to loop thru all registered resource bundles |
| foreach(var key in bundles.Keys) |
| { |
| Type clazz = bundles[key]; |
| ResourceManager resourceBundle = resourceManagerFactory.Create(clazz); |
| if (resourceBundle != null) |
| { |
| try |
| { |
| string obj = resourceBundle.GetString(messageKey, locale); |
| if (obj != null) |
| return obj; |
| } |
| #pragma warning disable 168 |
| catch (MissingManifestResourceException e) |
| #pragma warning restore 168 |
| { |
| // just continue it might be on the next resource bundle |
| } |
| finally |
| { |
| resourceManagerFactory.Release(resourceBundle); |
| } |
| } |
| } |
| // if resource is not found |
| return null; |
| } |
| |
| private static void Load(Type clazz) |
| { |
| FieldInfo[] fieldArray = clazz.GetFields(); |
| |
| // build a map of field names to Field objects |
| int len = fieldArray.Length; |
| IDictionary<string, FieldInfo> fields = new Dictionary<string, FieldInfo>(len * 2); |
| for (int i = 0; i < len; i++) |
| { |
| fields[fieldArray[i].Name] = fieldArray[i]; |
| LoadFieldValue(fieldArray[i], clazz); |
| } |
| } |
| |
| private static void LoadFieldValue(FieldInfo field, Type clazz) |
| { |
| field.SetValue(null, field.Name); |
| ValidateMessage(field.Name, clazz); |
| } |
| |
| /// <summary> |
| /// |
| /// </summary> |
| /// <param name="key">Message Key</param> |
| /// <param name="clazz"></param> |
| private static void ValidateMessage(string key, Type clazz) |
| { |
| // Test if the message is present in the resource bundle |
| try |
| { |
| ResourceManager resourceBundle = resourceManagerFactory.Create(clazz); |
| if (resourceBundle != null) |
| { |
| try |
| { |
| string obj = resourceBundle.GetString(key); |
| //if (obj == null) |
| // System.err.println("WARN: Message with key:" + key + " and locale: " |
| // + Locale.getDefault() + " not found."); |
| } |
| finally |
| { |
| resourceManagerFactory.Release(resourceBundle); |
| } |
| } |
| } |
| catch (MissingManifestResourceException) // LUCENENET: IDE0059: Remove unnecessary value assignment |
| { |
| //System.err.println("WARN: Message with key:" + key + " and locale: " |
| // + Locale.getDefault() + " not found."); |
| } |
| catch (Exception) // LUCENENET: IDE0059: Remove unnecessary value assignment |
| { |
| // ignore all other errors and exceptions |
| // since this code is just a test to see if the message is present on the |
| // system |
| } |
| } |
| } |
| } |