예제 #1
0
        /// <summary>
        /// Reloads the internal SPI list.
        /// Changes to the service list are visible after the method ends, all
        /// iterators (e.g, from <see cref="AvailableServices"/>,...) stay consistent.
        ///
        /// <para/><b>NOTE:</b> Only new service providers are added, existing ones are
        /// never removed or replaced.
        ///
        /// <para/><em>this method is expensive and should only be called for discovery
        /// of new service providers on the given classpath/classloader!</em>
        /// </summary>
        public void Reload()
        {
            UninterruptableMonitor.Enter(this);
            try
            {
                IDictionary <string, Type> services = new JCG.LinkedDictionary <string, Type>(this.services);
                SPIClassIterator <S>       loader   = SPIClassIterator <S> .Get();

                foreach (var service in loader)
                {
                    string clazzName = service.Name;
                    string name      = null;
                    foreach (string suffix in suffixes)
                    {
                        if (clazzName.EndsWith(suffix, StringComparison.Ordinal))
                        {
                            name = clazzName.Substring(0, clazzName.Length - suffix.Length).ToLowerInvariant();
                            break;
                        }
                    }

                    if (name is null)
                    {
                        throw ServiceConfigurationError.Create("The class name " + service.Name +
                                                               " has wrong suffix, allowed are: " + Arrays.ToString(suffixes));
                    }
                    // only add the first one for each name, later services will be ignored
                    // this allows to place services before others in classpath to make
                    // them used instead of others
                    //
                    // TODO: Should we disallow duplicate names here?
                    // Allowing it may get confusing on collisions, as different packages
                    // could contain same factory class, which is a naming bug!
                    // When changing this be careful to allow reload()!
                    if (!services.ContainsKey(name))
                    {
                        services.Add(name, service);
                    }
                }
                this.services = services.AsReadOnly();
            }
            finally
            {
                UninterruptableMonitor.Exit(this);
            }
        }
예제 #2
0
        /// <summary>
        /// Reloads the internal SPI list.
        /// Changes to the service list are visible after the method ends, all
        /// iterators (e.g, from <see cref="AvailableServices"/>,...) stay consistent.
        ///
        /// <para/><b>NOTE:</b> Only new service providers are added, existing ones are
        /// never removed or replaced.
        ///
        /// <para/><em>this method is expensive and should only be called for discovery
        /// of new service providers on the given classpath/classloader!</em>
        /// </summary>
        public void Reload()
        {
            lock (this)
            {
                IDictionary <string, Type> services = new LinkedHashMap <string, Type>(this.services);
                SPIClassIterator <S>       loader   = SPIClassIterator <S> .Get();

                foreach (var service in loader)
                {
                    string clazzName = service.Name;
                    string name      = null;
                    foreach (string suffix in suffixes)
                    {
                        if (clazzName.EndsWith(suffix, StringComparison.Ordinal))
                        {
                            name = clazzName.Substring(0, clazzName.Length - suffix.Length).ToLowerInvariant();
                            break;
                        }
                    }

                    if (name == null)
                    {
                        throw new InvalidOperationException("The class name " + service.Name +
                                                            " has wrong suffix, allowed are: " + Arrays.ToString(suffixes));
                    }
                    // only add the first one for each name, later services will be ignored
                    // this allows to place services before others in classpath to make
                    // them used instead of others
                    //
                    // LUCENETODO: Should we disallow duplicate names here?
                    // Allowing it may get confusing on collisions, as different packages
                    // could contain same factory class, which is a naming bug!
                    // When changing this be careful to allow reload()!
                    if (!services.ContainsKey(name))
                    {
                        services.Add(name, service);
                    }
                }
                this.services = Collections.UnmodifiableMap(services);
            }
        }