public AnalysisSPILoader(Type clazz, string[] suffixes, ClassLoader classloader) { this.clazz = clazz; this.suffixes = suffixes; // if clazz' classloader is not a parent of the given one, we scan clazz's classloader, too: //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final ClassLoader clazzClassloader = clazz.getClassLoader(); ClassLoader clazzClassloader = clazz.ClassLoader; if (clazzClassloader != null && !SPIClassIterator.isParentClassLoader(clazzClassloader, classloader)) { reload(clazzClassloader); } reload(classloader); }
/// <summary> /// Reloads the internal SPI list from the given <seealso cref="ClassLoader"/>. /// Changes to the service list are visible after the method ends, all /// iterators (e.g., from <seealso cref="#availableServices()"/>,...) stay consistent. /// /// <para><b>NOTE:</b> Only new service providers are added, existing ones are /// never removed or replaced. /// /// </para> /// <para><em>This method is expensive and should only be called for discovery /// of new service providers on the given classpath/classloader!</em> /// </para> /// </summary> public void reload(ClassLoader classloader) { lock (this) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final java.util.LinkedHashMap<String,Class> services = new java.util.LinkedHashMap<>(this.services); LinkedHashMap <string, Type> services = new LinkedHashMap <string, Type>(this.services); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final org.apache.lucene.util.SPIClassIterator<S> loader = org.apache.lucene.util.SPIClassIterator.get(clazz, classloader); SPIClassIterator <S> loader = SPIClassIterator.get(clazz, classloader); while (loader.hasNext()) { //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final Class service = loader.next(); Type service = loader.next(); //JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final': //ORIGINAL LINE: final String clazzName = service.getSimpleName(); string clazzName = service.SimpleName; string name = null; foreach (string suffix in suffixes) { if (clazzName.EndsWith(suffix, StringComparison.Ordinal)) { name = clazzName.Substring(0, clazzName.Length - suffix.Length).ToLower(Locale.ROOT); break; } } if (name == null) { throw new ServiceConfigurationError("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.put(name, service); } } this.services = Collections.unmodifiableMap(services); } }
/// <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); } }
/// <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); } }