OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [java/] [util/] [ServiceLoader.java] - Blame information for rev 771

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 771 jeremybenn
/* ServiceLoader.java -- Allows loading of plug-in services.
2
   Copyright (C) 2006, 2007  Free Software Foundation
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
package java.util;
39
 
40
import gnu.classpath.ServiceFactory;
41
 
42
/**
43
 * <p>
44
 * Facilities for loading service providers.  A service is
45
 * defined by a set of interfaces or abstract classes, and
46
 * a service provider gives a concrete implementation of this.
47
 * Service providers may be installed as part of the runtime
48
 * environment using JAR files in the extension directories,
49
 * or may be simply supplied on the classpath.
50
 * </p>
51
 * <p>
52
 * In terms of loading a service, the service is defined by
53
 * a single interface or abstract class which the provider
54
 * implements.  This may not constitute the entire service,
55
 * but is simply a mechanism by which a provider of the
56
 * service can be loaded and its capabilities determined.
57
 * The variety of possible services means that no more
58
 * requirements are made of the service provider other than
59
 * that it must have an accessible zero argument constructor
60
 * in order to allow an instance to be created.
61
 * </p>
62
 * <p>
63
 * Service providers are listed in a file named after the
64
 * service type in the directory <code>META-INF/services</code>.
65
 * The file contains a list of classes, and must be encoded
66
 * using UTF-8.  Whitespace is ignored.  Comments can be
67
 * included by using a <code>'#'</code> prefix; anything occurring
68
 * on the same line after this symbol is ignored. Duplicate classes
69
 * are ignored.
70
 * </p>
71
 * <p>
72
 * The classes are loaded using the same classloader that was
73
 * queried in order to locate the configuration file.  As a result,
74
 * the providers do not need to reside in the same JAR file as the
75
 * resource; they merely have to be accessible to this classloader,
76
 * which may differ from the one that loaded the file itself.
77
 * </p>
78
 * <p>
79
 * Providers are located and instantiated lazily, as calls to the
80
 * {@link #iterator()} are made.  Providers are cached, and those in
81
 * the cache are returned first.  The cache may be cleared by calling
82
 * {@link #reload()}.  Service loaders always execute in the security
83
 * context of the caller, so ideally calls should be made from a trusted
84
 * source.
85
 * </p>
86
 * <p>
87
 * Note that this class is not thread-safe, and that strange errors may
88
 * occur as the result of the use of remote URLs occurring on the classpath,
89
 * which lead to erroneous web pages.
90
 * </p>
91
 *
92
 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
93
 * @since 1.6
94
 */
95
public final class ServiceLoader<S>
96
  implements Iterable<S>
97
{
98
 
99
  /**
100
   * The class of the service provider.
101
   */
102
  private Class<S> spi;
103
 
104
  /**
105
   * The class loader for the service provider.
106
   */
107
  private ClassLoader loader;
108
 
109
  /**
110
   * The cache of service providers.
111
   */
112
  private List<S> cache;
113
 
114
  /**
115
   * The {@link gnu.classpath.ServiceFactory} iterator
116
   * from which providers are obtained.
117
   */
118
  private Iterator<S> serviceIt;
119
 
120
  /**
121
   * Constructs a new {@link ServiceLoader} with
122
   * the specified provider and class loader.
123
   *
124
   * @param spi the service to load.
125
   * @param loader the class loader to use.
126
   */
127
  private ServiceLoader(Class<S> spi, ClassLoader loader)
128
  {
129
    this.spi = spi;
130
    this.loader = loader;
131
    cache = new ArrayList<S>();
132
  }
133
 
134
  /**
135
   * Lazily loads the available providers.  The iterator first returns
136
   * providers from the cache, in instantiation order, followed by any
137
   * remaining providers, which are added to the cache after loading.
138
   * The actual loading and parsing of the configuration file takes
139
   * place in the {@link Iterator#hasNext()} and {@link Iterator#next()}
140
   * methods, which means that they may result in a
141
   * {@link ServiceConfigurationError} being thrown.  If such an error
142
   * does occur, subsequent invocations will attempt to recover.
143
   * The {@link remove()} method is not supported and instead throws
144
   * an {@link UnsupportedOperationException}.
145
   *
146
   * @return an iterator that lazily loads service providers.
147
   */
148
  public Iterator<S> iterator()
149
  {
150
    return new Iterator<S>()
151
      {
152
        /**
153
         * The cache iterator.
154
         */
155
        private Iterator<S> cacheIt = cache.iterator();
156
 
157
        public boolean hasNext()
158
        {
159
          if (cacheIt.hasNext())
160
            return true;
161
          if (serviceIt == null)
162
            serviceIt =
163
              ServiceFactory.lookupProviders(spi, loader, true);
164
          return serviceIt.hasNext();
165
        }
166
 
167
        public S next()
168
        {
169
          if (cacheIt.hasNext())
170
            return cacheIt.next();
171
          if (serviceIt == null)
172
            serviceIt =
173
              ServiceFactory.lookupProviders(spi, loader, true);
174
          S nextService = serviceIt.next();
175
          cache.add(nextService);
176
          return nextService;
177
        }
178
 
179
        public void remove()
180
        {
181
          throw new UnsupportedOperationException();
182
        }
183
      };
184
  }
185
 
186
  /**
187
   * Creates a new service loader for the given service,
188
   * using the context class loader of the current thread.
189
   * This is equivalent to calling <code>ServiceLoader.load(service,
190
   * Thread.currentThread().getContextClassLoader())</code>.
191
   *
192
   * @param service the interface or abstract class that represents
193
   *                the service.
194
   * @return a new {@link ServiceLoader} instance.
195
   */
196
  public static <S> ServiceLoader<S> load(Class<S> service)
197
  {
198
    return load(service,
199
                Thread.currentThread().getContextClassLoader());
200
  }
201
 
202
  /**
203
   * Creates a new service loader for the given service,
204
   * using the specified class loader.  The class loader is
205
   * used to access the configuration file and the service
206
   * provider instances themselves.  If the loader is
207
   * <code>null</code>, the system class loader (or, if
208
   * this is also <code>null</code>, the bootstrap class
209
   * loader).
210
   *
211
   * @param service the interface or abstract class that represents
212
   *                the service.
213
   * @param loader the class loader used to load the configuration
214
   *               file and service providers.
215
   * @return a new {@link ServiceLoader} instance.
216
   */
217
  public static <S> ServiceLoader<S> load(Class<S> service,
218
                                          ClassLoader loader)
219
  {
220
    if (loader == null)
221
      loader = ClassLoader.getSystemClassLoader();
222
    return new ServiceLoader(service, loader);
223
  }
224
 
225
  /**
226
   * Creates a new service loader for the given service,
227
   * using the extension class loader.  If the extension
228
   * class loader can not be found, the system class loader
229
   * is used (or, if this is <code>null</code>, the
230
   * bootstrap class loader).  The primary use of this method
231
   * is to only obtain installed services, ignoring any which
232
   * may appear on the classpath.  This is equivalent to calling
233
   * <code>load(service, extClassLoader)</code> where
234
   * <code>extClassLoader</code> is the extension class loader
235
   * (or <code>null</code> if this is unavailable).
236
   *
237
   * @param service the interface or abstract class that represents
238
   *                the service.
239
   * @return a new {@link ServiceLoader} instance.
240
   */
241
  public static <S> ServiceLoader<S> loadInstalled(Class<S> service)
242
  {
243
    /* We expect the extension class loader to be the parent
244
     * of the system class loader, as in
245
     * ClassLoader.getDefaultSystemClassLoader() */
246
    return load(service,
247
                ClassLoader.getSystemClassLoader().getParent());
248
  }
249
 
250
  /**
251
   * Clears the cache of the provider, so that all providers
252
   * are again read from the configuration file and instantiated.
253
   */
254
  public void reload()
255
  {
256
    cache.clear();
257
  }
258
 
259
  /**
260
   * Returns a textual representation of this
261
   * {@link ServiceLoader}.
262
   *
263
   * @return a textual representation of the
264
   *         service loader.
265
   */
266
  public String toString()
267
  {
268
    return getClass().getName() +
269
      "[spi=" + spi +
270
      ",loader=" + loader +
271
      "]";
272
  }
273
 
274
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.