⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 servicefactory.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
  private static final class ServiceIterator    implements Iterator  {    /**     * The service provider interface (usually an interface, sometimes     * an abstract class) which the services must implement.     */    private final Class spi;    /**     * An Enumeration<URL> over the URLs that contain a resource     * <code>META-INF/services/&lt;org.foo.SomeService&gt;</code>,     * as returned by {@link ClassLoader#getResources(String)}.     */    private final Enumeration urls;    /**     * The class loader used for loading service providers.     */    private final ClassLoader loader;    /**     * The security context used when loading and initializing service     * providers. We want to load and initialize all plug-in service     * providers under the same security context, namely the one that     * was active when {@link #lookupProviders(Class, ClassLoader)} has     * been called.     */    private final AccessControlContext securityContext;    /**     * A reader for the current file listing class names of service     * implementors, or <code>null</code> when the last reader has     * been fetched.     */    private BufferedReader reader;        /**     * The URL currently being processed. This is only used for     * emitting error messages.     */    private URL currentURL;    /**     * The service provider that will be returned by the next call to     * {@link #next()}, or <code>null</code> if the iterator has     * already returned all service providers.     */    private Object nextProvider;    /**     * Constructs an Iterator that loads and initializes services on     * demand.     *     * @param spi the service provider interface which the services     * must implement. Usually, this is a Java interface type, but it     * might also be an abstract class or even a concrete superclass.     *     * @param urls an Enumeration<URL> over the URLs that contain a     * resource     * <code>META-INF/services/&lt;org.foo.SomeService&gt;</code>, as     * determined by {@link ClassLoader#getResources(String)}.     *     * @param loader the ClassLoader that gets used for loading     * service providers.     *     * @param securityContext the security context to use when loading     * and initializing service providers.     */    ServiceIterator(Class spi, Enumeration urls, ClassLoader loader,                    AccessControlContext securityContext)    {      this.spi = spi;      this.urls = urls;      this.loader = loader;      this.securityContext = securityContext;      this.nextProvider = loadNextServiceProvider();    }    /**     * @throws NoSuchElementException if {@link #hasNext} returns     * <code>false</code>.     */    public Object next()    {      Object result;      if (!hasNext())        throw new NoSuchElementException();      result = nextProvider;      nextProvider = loadNextServiceProvider();      return result;    }    public boolean hasNext()    {      return nextProvider != null;    }    public void remove()    {      throw new UnsupportedOperationException();    }    private Object loadNextServiceProvider()    {      String line;            if (reader == null)        advanceReader();      for (;;)        {          /* If we have reached the last provider list, we cannot           * retrieve any further lines.           */          if (reader == null)            return null;          try            {              line = reader.readLine();            }          catch (IOException readProblem)            {              log(Level.WARNING, "IOException upon reading {0}", currentURL,                  readProblem);              line = null;            }          /* When we are at the end of one list of services,           * switch over to the next one.           */          if (line == null)            {              advanceReader();              continue;            }          // Skip whitespace at the beginning and end of each line.          line = line.trim();          // Skip empty lines.          if (line.length() == 0)            continue;          // Skip comment lines.          if (line.charAt(0) == '#')            continue;          try            {              log(Level.FINE,                  "Loading service provider \"{0}\", specified"                  + " by \"META-INF/services/{1}\" in {2}.",                  new Object[] { line, spi.getName(), currentURL },                  null);              /* Load the class in the security context that was               * active when calling lookupProviders.               */              return AccessController.doPrivileged(                new ServiceProviderLoadingAction(spi, line, loader),                securityContext);            }          catch (Exception ex)            {              String msg = "Cannot load service provider class \"{0}\","                + " specified by \"META-INF/services/{1}\" in {2}";              if (ex instanceof PrivilegedActionException                  && ex.getCause() instanceof ClassCastException)                msg = "Service provider class \"{0}\" is not an instance"                  + " of \"{1}\". Specified"                  + " by \"META-INF/services/{1}\" in {2}.";              log(Level.WARNING, msg,                                    new Object[] { line, spi.getName(), currentURL },                  ex);              continue;            }        }    }    private void advanceReader()    {      do        {          if (reader != null)            {              try                {                  reader.close();                  log(Level.FINE, "closed {0}", currentURL, null);                }              catch (Exception ex)                {                  log(Level.WARNING, "cannot close {0}", currentURL, ex);                }              reader = null;              currentURL = null;            }        if (!urls.hasMoreElements())          return;        currentURL = (URL) urls.nextElement();        try          {            reader = new BufferedReader(new InputStreamReader(              currentURL.openStream(), "UTF-8"));            log(Level.FINE, "opened {0}", currentURL, null);          }        catch (Exception ex)          {            log(Level.WARNING, "cannot open {0}", currentURL, ex);          }        }      while (reader == null);    }  }  // Package-private to avoid a trampoline.  /**   * Passes a log message to the <code>java.util.logging</code>   * framework. This call returns very quickly if no log message will   * be produced, so there is not much overhead in the standard case.   *   * @param level the severity of the message, for instance {@link   * Level#WARNING}.   *   * @param msg the log message, for instance <code>&#x201c;Could not   * load {0}.&#x201d;</code>   *   * @param param the parameter(s) for the log message, or   * <code>null</code> if <code>msg</code> does not specify any   * parameters. If <code>param</code> is not an array, an array with   * <code>param</code> as its single element gets passed to the   * logging framework.   *   * @param t a Throwable that is associated with the log record, or   * <code>null</code> if the log message is not associated with a   * Throwable.   */  static void log(Level level, String msg, Object param, Throwable t)  {    LogRecord rec;    // Return quickly if no log message will be produced.    if (!LOGGER.isLoggable(level))      return;    rec = new LogRecord(level, msg);    if (param != null && param.getClass().isArray())      rec.setParameters((Object[]) param);    else      rec.setParameters(new Object[] { param });    rec.setThrown(t);    // While java.util.logging can sometimes infer the class and    // method of the caller, this automatic inference is not reliable    // on highly optimizing VMs. Also, log messages make more sense to    // developers when they display a public method in a public class;    // otherwise, they might feel tempted to figure out the internals    // of ServiceFactory in order to understand the problem.    rec.setSourceClassName(ServiceFactory.class.getName());    rec.setSourceMethodName("lookupProviders");    LOGGER.log(rec);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -