示例#1
0
 /**
  * Implementation of {@link #getServiceProviders(Class, Filter, Hints)} without the filtering
  * applied by the {@link #isAcceptable(Object, Class, Hints, Filter)} method. If this filtering is
  * not already presents in the filter given to this method, then it must be applied on the
  * elements returned by the iterator. The later is preferrable when:
  *
  * <p>
  *
  * <ul>
  *   <li>There is some cheaper tests to perform before {@code isAcceptable}.
  *   <li>We don't want a restrictive filter in order to avoid trigging a classpath scan if this
  *       method doesn't found any element to iterate.
  * </ul>
  *
  * <p><b>Note:</b> {@link #synchronizeIteratorProviders} should also be invoked once before this
  * method.
  *
  * @todo Use Hints to match Constructor.
  */
 final <T> Iterator<T> getUnfilteredProviders(final Class<T> category) {
   /*
    * If the map is not empty, then this mean that a scanning is under progress, i.e.
    * 'scanForPlugins' is currently being executed. This is okay as long as the user
    * is not asking for one of the categories under scanning. Otherwise, the answer
    * returned by 'getServiceProviders' would be incomplete because not all plugins
    * have been found yet. This can lead to some bugs hard to spot because this methoud
    * could complete normally but return the wrong plugin. It is safer to thrown an
    * exception so the user is advised that something is wrong.
    */
   if (scanningCategories.contains(category)) {
     throw new RecursiveSearchException(category);
   }
   scanForPluginsIfNeeded(category);
   return getServiceProviders(category, true);
 }
示例#2
0
 /**
  * Returns the providers in the registry for the specified category, filter and hints. Providers
  * that are not {@linkplain OptionalFactory#isAvailable available} will be ignored. This method
  * will {@linkplain #scanForPlugins() scan for plugins} the first time it is invoked for the given
  * category.
  *
  * @param <T> The class represented by the {@code category} argument.
  * @param category The category to look for. Usually an interface class (not the actual
  *     implementation class).
  * @param filter The optional filter, or {@code null}.
  * @param hints The optional user requirements, or {@code null}.
  * @return Factories ready to use for the specified category, filter and hints.
  * @since 2.3
  */
 public synchronized <T> Iterator<T> getServiceProviders(
     final Class<T> category, final Filter filter, final Hints hints) {
   /*
    * The implementation of this method is very similar to the 'getUnfilteredProviders'
    * one except for filter handling. See the comments in 'getUnfilteredProviders' for
    * more implementation details.
    */
   if (scanningCategories.contains(category)) {
     // Please note you will get errors here if you accidentally allow
     // more than one thread to use your FactoryRegistry at a time.
     throw new RecursiveSearchException(category);
   }
   final Filter hintsFilter =
       new Filter() {
         public boolean filter(final Object provider) {
           return isAcceptable(category.cast(provider), category, hints, filter);
         }
       };
   synchronizeIteratorProviders();
   scanForPluginsIfNeeded(category);
   return getServiceProviders(category, hintsFilter, true);
 }