Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/javax/imageio/spi/IIORegistry.java
38830 views
/*1* Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package javax.imageio.spi;2627import java.security.PrivilegedAction;28import java.security.AccessController;29import java.util.HashMap;30import java.util.Iterator;31import java.util.Map;32import java.util.NoSuchElementException;33import java.util.Set;34import java.util.Vector;35import com.sun.imageio.spi.FileImageInputStreamSpi;36import com.sun.imageio.spi.FileImageOutputStreamSpi;37import com.sun.imageio.spi.InputStreamImageInputStreamSpi;38import com.sun.imageio.spi.OutputStreamImageOutputStreamSpi;39import com.sun.imageio.spi.RAFImageInputStreamSpi;40import com.sun.imageio.spi.RAFImageOutputStreamSpi;41import com.sun.imageio.plugins.gif.GIFImageReaderSpi;42import com.sun.imageio.plugins.gif.GIFImageWriterSpi;43import com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi;44import com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi;45import com.sun.imageio.plugins.png.PNGImageReaderSpi;46import com.sun.imageio.plugins.png.PNGImageWriterSpi;47import com.sun.imageio.plugins.bmp.BMPImageReaderSpi;48import com.sun.imageio.plugins.bmp.BMPImageWriterSpi;49import com.sun.imageio.plugins.wbmp.WBMPImageReaderSpi;50import com.sun.imageio.plugins.wbmp.WBMPImageWriterSpi;51import sun.awt.AppContext;52import java.util.ServiceLoader;53import java.util.ServiceConfigurationError;5455/**56* A registry for service provider instances. Service provider57* classes may be detected at run time by means of meta-information in58* the JAR files containing them. The intent is that it be relatively59* inexpensive to load and inspect all available service provider60* classes. These classes may them be used to locate and instantiate61* more heavyweight classes that will perform actual work, in this62* case instances of <code>ImageReader</code>,63* <code>ImageWriter</code>, <code>ImageTranscoder</code>,64* <code>ImageInputStream</code>, and <code>ImageOutputStream</code>.65*66* <p> Service providers found on the system classpath (typically67* the <code>lib/ext</code> directory in the Java68* installation directory) are automatically loaded as soon as this class is69* instantiated.70*71* <p> When the <code>registerApplicationClasspathSpis</code> method72* is called, service provider instances declared in the73* meta-information section of JAR files on the application class path74* are loaded. To declare a service provider, a <code>services</code>75* subdirectory is placed within the <code>META-INF</code> directory76* that is present in every JAR file. This directory contains a file77* for each service provider interface that has one or more78* implementation classes present in the JAR file. For example, if79* the JAR file contained a class named80* <code>com.mycompany.imageio.MyFormatReaderSpi</code> which81* implements the <code>ImageReaderSpi</code> interface, the JAR file82* would contain a file named:83*84* <pre>85* META-INF/services/javax.imageio.spi.ImageReaderSpi86* </pre>87*88* containing the line:89*90* <pre>91* com.mycompany.imageio.MyFormatReaderSpi92* </pre>93*94* <p> The service provider classes are intended to be lightweight95* and quick to load. Implementations of these interfaces96* should avoid complex dependencies on other classes and on97* native code.98*99* <p> It is also possible to manually add service providers not found100* automatically, as well as to remove those that are using the101* interfaces of the <code>ServiceRegistry</code> class. Thus102* the application may customize the contents of the registry as it103* sees fit.104*105* <p> For more details on declaring service providers, and the JAR106* format in general, see the <a107* href="{@docRoot}/../technotes/guides/jar/jar.html">108* JAR File Specification</a>.109*110*/111public final class IIORegistry extends ServiceRegistry {112113/**114* A <code>Vector</code> containing the valid IIO registry115* categories (superinterfaces) to be used in the constructor.116*/117private static final Vector initialCategories = new Vector(5);118119static {120initialCategories.add(ImageReaderSpi.class);121initialCategories.add(ImageWriterSpi.class);122initialCategories.add(ImageTranscoderSpi.class);123initialCategories.add(ImageInputStreamSpi.class);124initialCategories.add(ImageOutputStreamSpi.class);125}126127/**128* Set up the valid service provider categories and automatically129* register all available service providers.130*131* <p> The constructor is private in order to prevent creation of132* additional instances.133*/134private IIORegistry() {135super(initialCategories.iterator());136registerStandardSpis();137registerApplicationClasspathSpis();138}139140/**141* Returns the default <code>IIORegistry</code> instance used by142* the Image I/O API. This instance should be used for all143* registry functions.144*145* <p> Each <code>ThreadGroup</code> will receive its own146* instance; this allows different <code>Applet</code>s in the147* same browser (for example) to each have their own registry.148*149* @return the default registry for the current150* <code>ThreadGroup</code>.151*/152public static IIORegistry getDefaultInstance() {153AppContext context = AppContext.getAppContext();154IIORegistry registry =155(IIORegistry)context.get(IIORegistry.class);156if (registry == null) {157// Create an instance for this AppContext158registry = new IIORegistry();159context.put(IIORegistry.class, registry);160}161return registry;162}163164private void registerStandardSpis() {165// Hardwire standard SPIs166registerServiceProvider(new GIFImageReaderSpi());167registerServiceProvider(new GIFImageWriterSpi());168registerServiceProvider(new BMPImageReaderSpi());169registerServiceProvider(new BMPImageWriterSpi());170registerServiceProvider(new WBMPImageReaderSpi());171registerServiceProvider(new WBMPImageWriterSpi());172registerServiceProvider(new PNGImageReaderSpi());173registerServiceProvider(new PNGImageWriterSpi());174registerServiceProvider(new JPEGImageReaderSpi());175registerServiceProvider(new JPEGImageWriterSpi());176registerServiceProvider(new FileImageInputStreamSpi());177registerServiceProvider(new FileImageOutputStreamSpi());178registerServiceProvider(new InputStreamImageInputStreamSpi());179registerServiceProvider(new OutputStreamImageOutputStreamSpi());180registerServiceProvider(new RAFImageInputStreamSpi());181registerServiceProvider(new RAFImageOutputStreamSpi());182183registerInstalledProviders();184}185186/**187* Registers all available service providers found on the188* application class path, using the default189* <code>ClassLoader</code>. This method is typically invoked by190* the <code>ImageIO.scanForPlugins</code> method.191*192* @see javax.imageio.ImageIO#scanForPlugins193* @see ClassLoader#getResources194*/195public void registerApplicationClasspathSpis() {196// FIX: load only from application classpath197198ClassLoader loader = Thread.currentThread().getContextClassLoader();199200Iterator categories = getCategories();201while (categories.hasNext()) {202Class<IIOServiceProvider> c = (Class)categories.next();203Iterator<IIOServiceProvider> riter =204ServiceLoader.load(c, loader).iterator();205while (riter.hasNext()) {206try {207// Note that the next() call is required to be inside208// the try/catch block; see 6342404.209IIOServiceProvider r = riter.next();210registerServiceProvider(r);211} catch (ServiceConfigurationError err) {212if (System.getSecurityManager() != null) {213// In the applet case, we will catch the error so214// registration of other plugins can proceed215err.printStackTrace();216} else {217// In the application case, we will throw the218// error to indicate app/system misconfiguration219throw err;220}221}222}223}224}225226private void registerInstalledProviders() {227/*228We need to load installed providers from the229system classpath (typically the <code>lib/ext</code>230directory in in the Java installation directory)231in the privileged mode in order to232be able read corresponding jar files even if233file read capability is restricted (like the234applet context case).235*/236PrivilegedAction doRegistration =237new PrivilegedAction() {238public Object run() {239Iterator categories = getCategories();240while (categories.hasNext()) {241Class<IIOServiceProvider> c = (Class)categories.next();242for (IIOServiceProvider p : ServiceLoader.loadInstalled(c)) {243registerServiceProvider(p);244}245}246return this;247}248};249250AccessController.doPrivileged(doRegistration);251}252}253254255