You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by ni...@apache.org on 2016/12/06 15:12:18 UTC

[43/58] lucenenet git commit: QueryParser.Flexible refactor: Added dependency injection point (IResourceManagerFactory) that can be used to either change the convention used to locate embedded resources or to retrieve them from an external source.

QueryParser.Flexible refactor: Added dependency injection point (IResourceManagerFactory) that can be used to either change the convention used to locate embedded resources or to retrieve them from an external source.


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/4c85b79a
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/4c85b79a
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/4c85b79a

Branch: refs/heads/master
Commit: 4c85b79af811bd9c5a2b916833a46429bb6ae827
Parents: c6696fe
Author: Shad Storhaug <sh...@shadstorhaug.com>
Authored: Mon Dec 5 23:05:38 2016 +0700
Committer: Shad Storhaug <sh...@shadstorhaug.com>
Committed: Mon Dec 5 23:05:38 2016 +0700

----------------------------------------------------------------------
 src/Lucene.Net.Core/Lucene.Net.csproj           |  2 +
 .../Support/BundleResourceManagerFactory.cs     | 69 ++++++++++++++++++++
 .../Support/IResourceManagerFactory.cs          | 19 ++++++
 .../Flexible/Core/Nodes/QueryNodeImpl.cs        | 13 +++-
 .../Flexible/Messages/NLS.cs                    | 69 ++++++++++++++------
 5 files changed, 150 insertions(+), 22 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4c85b79a/src/Lucene.Net.Core/Lucene.Net.csproj
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Lucene.Net.csproj b/src/Lucene.Net.Core/Lucene.Net.csproj
index 85ab464..f6e0d2f 100644
--- a/src/Lucene.Net.Core/Lucene.Net.csproj
+++ b/src/Lucene.Net.Core/Lucene.Net.csproj
@@ -614,6 +614,7 @@
     <Compile Include="Support\BitSetSupport.cs" />
     <Compile Include="Support\BufferExceptions.cs" />
     <Compile Include="Support\BuildType.cs" />
+    <Compile Include="Support\BundleResourceManagerFactory.cs" />
     <Compile Include="Support\ByteArrayOutputStream.cs" />
     <Compile Include="Support\ByteBuffer.cs" />
     <Compile Include="Support\ByteOrder.cs" />
@@ -642,6 +643,7 @@
     <Compile Include="Support\IdentityHashSet.cs" />
     <Compile Include="Support\IdentityWeakReference.cs" />
     <Compile Include="Support\IDictionaryExtensions.cs" />
+    <Compile Include="Support\IResourceManagerFactory.cs" />
     <Compile Include="Support\LimitedConcurrencyLevelTaskScheduler.cs" />
     <Compile Include="Support\LinkedHashMap.cs" />
     <Compile Include="Support\ListExtensions.cs" />

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4c85b79a/src/Lucene.Net.Core/Support/BundleResourceManagerFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Support/BundleResourceManagerFactory.cs b/src/Lucene.Net.Core/Support/BundleResourceManagerFactory.cs
new file mode 100644
index 0000000..49b7471
--- /dev/null
+++ b/src/Lucene.Net.Core/Support/BundleResourceManagerFactory.cs
@@ -0,0 +1,69 @@
+\ufeffusing System;
+using System.Resources;
+
+namespace Lucene.Net.Support
+{
+    /// <summary>
+    /// This implementation of <see cref="IResourceManagerFactory"/> uses a convention
+    /// to retrieve resources. In Java NLS, the convention is to use the same name for the
+    /// resource key propeties and for the resource file names. This presents a problem
+    /// for .NET because the resource generator already creates an internal class with the
+    /// same name as the <c>.resx</c> file.
+    /// <para/>
+    /// To work around this, we use the convention of appending the suffix "Bundle" to 
+    /// the end of the type the resource key propeties are stored in. For example,
+    /// if our constants are stored in a class named ErrorMessages, the type
+    /// that will be looked up by this factory will be ErrorMessagesBundle (which is the
+    /// name of the <c>.resx</c> file that should be added to your project).
+    /// <para/>
+    /// This implementation can be inherited to use a different convention or can be replaced
+    /// to get the resources from an external source.
+    /// </summary>
+    public class BundleResourceManagerFactory : IResourceManagerFactory
+    {
+        /// <summary>
+        /// Creates a <see cref="ResourceManager"/> instance using the specified <paramref name="resourceSource"/>.
+        /// </summary>
+        /// <param name="resourceSource">The type representing the resource to retrieve.</param>
+        /// <returns>A new <see cref="ResourceManager"/> instance.</returns>
+        public virtual ResourceManager Create(Type resourceSource)
+        {
+            return new ResourceManager(GetResourceType(resourceSource));
+        }
+
+        /// <summary>
+        /// Releases the <see cref="ResourceManager"/> instance including any disposable dependencies.
+        /// </summary>
+        /// <param name="manager">The <see cref="ResourceManager"/> to release.</param>
+        public virtual void Release(ResourceManager manager)
+        {
+            var disposable = manager as IDisposable;
+            if (disposable != null)
+            {
+                disposable.Dispose();
+            }
+        }
+
+        /// <summary>
+        /// Converts the Java NLS type to the .NET resource type.
+        /// In Java, these were one and the same, but in .NET it is not possible to create resources
+        /// in Visual Studio with the same class name as a resource class because the resource generation process already
+        /// creates a backing class with the same name as the resource. So, by convention the resources must be
+        /// named &lt;messages class name&gt; + <see cref="ResourceSuffix"/> (default value "Bundle") in order to be found by NLS.
+        /// </summary>
+        /// <param name="clazz">The type of the NLS class where the field strings are located that identify resources.</param>
+        /// <returns>The type of resources (the class name + <see cref="ResourceSuffix"/>), as a .NET <see cref="Type"/> instance.</returns>
+        protected virtual Type GetResourceType(Type clazz)
+        {
+            return Type.GetType(string.Concat(clazz.Namespace, ".", clazz.Name, ResourceSuffix, ", ", clazz.Assembly.FullName));
+        }
+
+        /// <summary>
+        /// The suffix to append to the resource key class name to locate the embedded resource.
+        /// </summary>
+        protected virtual string ResourceSuffix
+        {
+            get { return "Bundle"; }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4c85b79a/src/Lucene.Net.Core/Support/IResourceManagerFactory.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Support/IResourceManagerFactory.cs b/src/Lucene.Net.Core/Support/IResourceManagerFactory.cs
new file mode 100644
index 0000000..3038064
--- /dev/null
+++ b/src/Lucene.Net.Core/Support/IResourceManagerFactory.cs
@@ -0,0 +1,19 @@
+\ufeffusing System;
+using System.Resources;
+
+namespace Lucene.Net.Support
+{
+    /// <summary>
+    /// LUCENENET specific interface used to inject instances of
+    /// <see cref="ResourceManager"/>. This
+    /// extension point can be used to override the default behavior
+    /// to, for example, retrieve resources from a persistent data store,
+    /// rather than getting them from resource files.
+    /// </summary>
+    public interface IResourceManagerFactory
+    {
+        ResourceManager Create(Type resourceSource);
+
+        void Release(ResourceManager manager);
+    }
+}

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4c85b79a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs
index c3c3dcc..7ec817c 100644
--- a/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs
+++ b/src/Lucene.Net.QueryParser/Flexible/Core/Nodes/QueryNodeImpl.cs
@@ -92,8 +92,17 @@ namespace Lucene.Net.QueryParsers.Flexible.Core.Nodes
         {
             if (IsLeaf || this.clauses == null)
             {
-                ResourceManager bundle = new ResourceManager(typeof(QueryParserMessagesBundle));
-                string message = bundle.GetString(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED);
+                var factory = NLS.GetResourceManagerFactory();
+                ResourceManager bundle = factory.Create(typeof(QueryParserMessages));
+                string message;
+                try
+                {
+                    message = bundle.GetString(QueryParserMessages.NODE_ACTION_NOT_SUPPORTED);
+                }
+                finally
+                {
+                    factory.Release(bundle);
+                }
 
                 throw new ArgumentException(message);
             }

http://git-wip-us.apache.org/repos/asf/lucenenet/blob/4c85b79a/src/Lucene.Net.QueryParser/Flexible/Messages/NLS.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.QueryParser/Flexible/Messages/NLS.cs b/src/Lucene.Net.QueryParser/Flexible/Messages/NLS.cs
index 17d5a13..c076f9c 100644
--- a/src/Lucene.Net.QueryParser/Flexible/Messages/NLS.cs
+++ b/src/Lucene.Net.QueryParser/Flexible/Messages/NLS.cs
@@ -40,6 +40,11 @@ namespace Lucene.Net.QueryParsers.Flexible.Messages
     /// </summary>
     public class NLS
     {
+        /// <summary>
+        /// LUCENENET specific factory reference to inject instances of <see cref="ResourceManager"/>
+        /// into this class.
+        /// </summary>
+        private static IResourceManagerFactory resourceManagerFactory = new BundleResourceManagerFactory();
         private static IDictionary<string, Type> bundles = new Dictionary<string, Type>(0);
 
         protected NLS()
@@ -47,6 +52,33 @@ namespace Lucene.Net.QueryParsers.Flexible.Messages
             // 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)
+        {
+            if (resourceManagerFactory == null)
+            {
+                throw new ArgumentNullException("resourceManagerFactory");
+            }
+            NLS.resourceManagerFactory = resourceManagerFactory;
+        }
+
         public static string GetLocalizedMessage(string key)
         {
             return GetLocalizedMessage(key, CultureInfo.InvariantCulture);
@@ -112,7 +144,7 @@ namespace Lucene.Net.QueryParsers.Flexible.Messages
                 for (IEnumerator<string> it = bundles.Keys.GetEnumerator(); it.MoveNext();)
                 {
                     Type clazz = bundles[it.Current];
-                    ResourceManager resourceBundle = new ResourceManager(GetResourceType(clazz));
+                    ResourceManager resourceBundle = resourceManagerFactory.Create(clazz);
                     if (resourceBundle != null)
                     {
                         try
@@ -125,6 +157,10 @@ namespace Lucene.Net.QueryParsers.Flexible.Messages
                         {
                             // just continue it might be on the next resource bundle
                         }
+                        finally
+                        {
+                            resourceManagerFactory.Release(resourceBundle);
+                        }
                     }
                 }
                 // if resource is not found
@@ -162,13 +198,20 @@ namespace Lucene.Net.QueryParsers.Flexible.Messages
             // Test if the message is present in the resource bundle
             try
             {
-                ResourceManager resourceBundle = new ResourceManager(GetResourceType(clazz));
+                ResourceManager resourceBundle = resourceManagerFactory.Create(clazz);
                 if (resourceBundle != null)
                 {
-                    object obj = resourceBundle.GetObject(key);
-                    //if (obj == null)
-                    //  System.err.println("WARN: Message with key:" + key + " and locale: "
-                    //      + Locale.getDefault() + " not found.");
+                    try
+                    {
+                        object obj = resourceBundle.GetObject(key);
+                        //if (obj == null)
+                        //  System.err.println("WARN: Message with key:" + key + " and locale: "
+                        //      + Locale.getDefault() + " not found.");
+                    }
+                    finally
+                    {
+                        resourceManagerFactory.Release(resourceBundle);
+                    }
                 }
             }
             catch (MissingManifestResourceException e)
@@ -183,19 +226,5 @@ namespace Lucene.Net.QueryParsers.Flexible.Messages
                 // system
             }
         }
-
-        /// <summary>
-        /// LUCENENET specific method for converting the NLS type to the .NET resource type.
-        /// In Java, these were one and the same, but in .NET it is not possible to create resources
-        /// in Visual Studio with the same class name as a resource class because the resource generation process already
-        /// creates a backing class with the same name as the resource. So, by convention the resources must be
-        /// named &lt;messages class name&gt;Bundle in order to be found by NLS.
-        /// </summary>
-        /// <param name="clazz">The type of the NLS class where the field strings are located that identify resources.</param>
-        /// <returns>The type of resources (the class name + "Resources" suffix), as a .NET <see cref="Type"/> instance.</returns>
-        private static Type GetResourceType(Type clazz)
-        {
-            return Type.GetType(clazz.Namespace + "." + clazz.Name + "Bundle, " + clazz.Assembly.FullName);
-        }
     }
 }