43 import com.sun.imageio.plugins.gif.GIFImageWriterSpi; 44 import com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi; 45 import com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi; 46 import com.sun.imageio.plugins.png.PNGImageReaderSpi; 47 import com.sun.imageio.plugins.png.PNGImageWriterSpi; 48 import com.sun.imageio.plugins.bmp.BMPImageReaderSpi; 49 import com.sun.imageio.plugins.bmp.BMPImageWriterSpi; 50 import com.sun.imageio.plugins.wbmp.WBMPImageReaderSpi; 51 import com.sun.imageio.plugins.wbmp.WBMPImageWriterSpi; 52 import sun.awt.AppContext; 53 import java.util.ServiceLoader; 54 import java.util.ServiceConfigurationError; 55 56 /** 57 * A registry for service provider instances. Service provider 58 * classes may be detected at run time by means of meta-information in 59 * the JAR files containing them. The intent is that it be relatively 60 * inexpensive to load and inspect all available service provider 61 * classes. These classes may them be used to locate and instantiate 62 * more heavyweight classes that will perform actual work, in this 63 * case instances of <code>ImageReader</code>, 64 * <code>ImageWriter</code>, <code>ImageTranscoder</code>, 65 * <code>ImageInputStream</code>, and <code>ImageOutputStream</code>. 66 * 67 * Service providers found from the Java platform are automatically 68 * loaded as soon as this class is instantiated. 69 * 70 * <p> When the <code>registerApplicationClasspathSpis</code> method 71 * is called, service provider instances declared in the 72 * meta-information section of JAR files on the application class path 73 * are loaded. To declare a service provider, a <code>services</code> 74 * subdirectory is placed within the <code>META-INF</code> directory 75 * that is present in every JAR file. This directory contains a file 76 * for each service provider interface that has one or more 77 * implementation classes present in the JAR file. For example, if 78 * the JAR file contained a class named 79 * <code>com.mycompany.imageio.MyFormatReaderSpi</code> which 80 * implements the <code>ImageReaderSpi</code> interface, the JAR file 81 * would contain a file named: 82 * 83 * <pre> 84 * META-INF/services/javax.imageio.spi.ImageReaderSpi 85 * </pre> 86 * 87 * containing the line: 88 * 89 * <pre> 90 * com.mycompany.imageio.MyFormatReaderSpi 91 * </pre> 92 * 93 * <p> The service provider classes are intended to be lightweight 94 * and quick to load. Implementations of these interfaces 95 * should avoid complex dependencies on other classes and on 96 * native code. 97 * 98 * <p> It is also possible to manually add service providers not found 99 * automatically, as well as to remove those that are using the 100 * interfaces of the <code>ServiceRegistry</code> class. Thus 101 * the application may customize the contents of the registry as it 102 * sees fit. 103 * 104 * <p> For more details on declaring service providers, and the JAR 105 * format in general, see the <a 106 * href="{@docRoot}/../technotes/guides/jar/jar.html"> 107 * JAR File Specification</a>. 108 * 109 */ 110 public final class IIORegistry extends ServiceRegistry { 111 112 /** 113 * A <code>Vector</code> containing the valid IIO registry 114 * categories (superinterfaces) to be used in the constructor. 115 */ 116 private static final Vector<Class<?>> initialCategories = new Vector<>(5); 117 118 static { 119 initialCategories.add(ImageReaderSpi.class); 120 initialCategories.add(ImageWriterSpi.class); 121 initialCategories.add(ImageTranscoderSpi.class); 122 initialCategories.add(ImageInputStreamSpi.class); 123 initialCategories.add(ImageOutputStreamSpi.class); 124 } 125 126 /** 127 * Set up the valid service provider categories and automatically 128 * register all available service providers. 129 * 130 * <p> The constructor is private in order to prevent creation of 131 * additional instances. 132 */ 133 private IIORegistry() { 134 super(initialCategories.iterator()); 135 registerStandardSpis(); 136 registerApplicationClasspathSpis(); 137 } 138 139 /** 140 * Returns the default <code>IIORegistry</code> instance used by 141 * the Image I/O API. This instance should be used for all 142 * registry functions. 143 * 144 * <p> Each <code>ThreadGroup</code> will receive its own 145 * instance; this allows different <code>Applet</code>s in the 146 * same browser (for example) to each have their own registry. 147 * 148 * @return the default registry for the current 149 * <code>ThreadGroup</code>. 150 */ 151 public static IIORegistry getDefaultInstance() { 152 AppContext context = AppContext.getAppContext(); 153 IIORegistry registry = 154 (IIORegistry)context.get(IIORegistry.class); 155 if (registry == null) { 156 // Create an instance for this AppContext 157 registry = new IIORegistry(); 158 context.put(IIORegistry.class, registry); 159 } 160 return registry; 161 } 162 163 private void registerStandardSpis() { 164 // Hardwire standard SPIs 165 registerServiceProvider(new GIFImageReaderSpi()); 166 registerServiceProvider(new GIFImageWriterSpi()); 167 registerServiceProvider(new BMPImageReaderSpi()); 168 registerServiceProvider(new BMPImageWriterSpi()); 169 registerServiceProvider(new WBMPImageReaderSpi()); 170 registerServiceProvider(new WBMPImageWriterSpi()); 171 registerServiceProvider(new PNGImageReaderSpi()); 172 registerServiceProvider(new PNGImageWriterSpi()); 173 registerServiceProvider(new JPEGImageReaderSpi()); 174 registerServiceProvider(new JPEGImageWriterSpi()); 175 registerServiceProvider(new FileImageInputStreamSpi()); 176 registerServiceProvider(new FileImageOutputStreamSpi()); 177 registerServiceProvider(new InputStreamImageInputStreamSpi()); 178 registerServiceProvider(new OutputStreamImageOutputStreamSpi()); 179 registerServiceProvider(new RAFImageInputStreamSpi()); 180 registerServiceProvider(new RAFImageOutputStreamSpi()); 181 182 registerInstalledProviders(); 183 } 184 185 /** 186 * Registers all available service providers found on the 187 * application class path, using the default 188 * <code>ClassLoader</code>. This method is typically invoked by 189 * the <code>ImageIO.scanForPlugins</code> method. 190 * 191 * @see javax.imageio.ImageIO#scanForPlugins 192 * @see ClassLoader#getResources 193 */ 194 public void registerApplicationClasspathSpis() { 195 // FIX: load only from application classpath 196 197 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 198 199 Iterator<Class<?>> categories = getCategories(); 200 while (categories.hasNext()) { 201 @SuppressWarnings("unchecked") 202 Class<IIOServiceProvider> c = (Class<IIOServiceProvider>)categories.next(); 203 Iterator<IIOServiceProvider> riter = 204 ServiceLoader.load(c, loader).iterator(); 205 while (riter.hasNext()) { 206 try { 207 // Note that the next() call is required to be inside 208 // the try/catch block; see 6342404. 209 IIOServiceProvider r = riter.next(); | 43 import com.sun.imageio.plugins.gif.GIFImageWriterSpi; 44 import com.sun.imageio.plugins.jpeg.JPEGImageReaderSpi; 45 import com.sun.imageio.plugins.jpeg.JPEGImageWriterSpi; 46 import com.sun.imageio.plugins.png.PNGImageReaderSpi; 47 import com.sun.imageio.plugins.png.PNGImageWriterSpi; 48 import com.sun.imageio.plugins.bmp.BMPImageReaderSpi; 49 import com.sun.imageio.plugins.bmp.BMPImageWriterSpi; 50 import com.sun.imageio.plugins.wbmp.WBMPImageReaderSpi; 51 import com.sun.imageio.plugins.wbmp.WBMPImageWriterSpi; 52 import sun.awt.AppContext; 53 import java.util.ServiceLoader; 54 import java.util.ServiceConfigurationError; 55 56 /** 57 * A registry for service provider instances. Service provider 58 * classes may be detected at run time by means of meta-information in 59 * the JAR files containing them. The intent is that it be relatively 60 * inexpensive to load and inspect all available service provider 61 * classes. These classes may them be used to locate and instantiate 62 * more heavyweight classes that will perform actual work, in this 63 * case instances of {@code ImageReader}, 64 * {@code ImageWriter}, {@code ImageTranscoder}, 65 * {@code ImageInputStream}, and {@code ImageOutputStream}. 66 * 67 * Service providers found from the Java platform are automatically 68 * loaded as soon as this class is instantiated. 69 * 70 * <p> When the {@code registerApplicationClasspathSpis} method 71 * is called, service provider instances declared in the 72 * meta-information section of JAR files on the application class path 73 * are loaded. To declare a service provider, a {@code services} 74 * subdirectory is placed within the {@code META-INF} directory 75 * that is present in every JAR file. This directory contains a file 76 * for each service provider interface that has one or more 77 * implementation classes present in the JAR file. For example, if 78 * the JAR file contained a class named 79 * {@code com.mycompany.imageio.MyFormatReaderSpi} which 80 * implements the {@code ImageReaderSpi} interface, the JAR file 81 * would contain a file named: 82 * 83 * <pre> 84 * META-INF/services/javax.imageio.spi.ImageReaderSpi 85 * </pre> 86 * 87 * containing the line: 88 * 89 * <pre> 90 * com.mycompany.imageio.MyFormatReaderSpi 91 * </pre> 92 * 93 * <p> The service provider classes are intended to be lightweight 94 * and quick to load. Implementations of these interfaces 95 * should avoid complex dependencies on other classes and on 96 * native code. 97 * 98 * <p> It is also possible to manually add service providers not found 99 * automatically, as well as to remove those that are using the 100 * interfaces of the {@code ServiceRegistry} class. Thus 101 * the application may customize the contents of the registry as it 102 * sees fit. 103 * 104 * <p> For more details on declaring service providers, and the JAR 105 * format in general, see the <a 106 * href="{@docRoot}/../technotes/guides/jar/jar.html"> 107 * JAR File Specification</a>. 108 * 109 */ 110 public final class IIORegistry extends ServiceRegistry { 111 112 /** 113 * A {@code Vector} containing the valid IIO registry 114 * categories (superinterfaces) to be used in the constructor. 115 */ 116 private static final Vector<Class<?>> initialCategories = new Vector<>(5); 117 118 static { 119 initialCategories.add(ImageReaderSpi.class); 120 initialCategories.add(ImageWriterSpi.class); 121 initialCategories.add(ImageTranscoderSpi.class); 122 initialCategories.add(ImageInputStreamSpi.class); 123 initialCategories.add(ImageOutputStreamSpi.class); 124 } 125 126 /** 127 * Set up the valid service provider categories and automatically 128 * register all available service providers. 129 * 130 * <p> The constructor is private in order to prevent creation of 131 * additional instances. 132 */ 133 private IIORegistry() { 134 super(initialCategories.iterator()); 135 registerStandardSpis(); 136 registerApplicationClasspathSpis(); 137 } 138 139 /** 140 * Returns the default {@code IIORegistry} instance used by 141 * the Image I/O API. This instance should be used for all 142 * registry functions. 143 * 144 * <p> Each {@code ThreadGroup} will receive its own 145 * instance; this allows different {@code Applet}s in the 146 * same browser (for example) to each have their own registry. 147 * 148 * @return the default registry for the current 149 * {@code ThreadGroup}. 150 */ 151 public static IIORegistry getDefaultInstance() { 152 AppContext context = AppContext.getAppContext(); 153 IIORegistry registry = 154 (IIORegistry)context.get(IIORegistry.class); 155 if (registry == null) { 156 // Create an instance for this AppContext 157 registry = new IIORegistry(); 158 context.put(IIORegistry.class, registry); 159 } 160 return registry; 161 } 162 163 private void registerStandardSpis() { 164 // Hardwire standard SPIs 165 registerServiceProvider(new GIFImageReaderSpi()); 166 registerServiceProvider(new GIFImageWriterSpi()); 167 registerServiceProvider(new BMPImageReaderSpi()); 168 registerServiceProvider(new BMPImageWriterSpi()); 169 registerServiceProvider(new WBMPImageReaderSpi()); 170 registerServiceProvider(new WBMPImageWriterSpi()); 171 registerServiceProvider(new PNGImageReaderSpi()); 172 registerServiceProvider(new PNGImageWriterSpi()); 173 registerServiceProvider(new JPEGImageReaderSpi()); 174 registerServiceProvider(new JPEGImageWriterSpi()); 175 registerServiceProvider(new FileImageInputStreamSpi()); 176 registerServiceProvider(new FileImageOutputStreamSpi()); 177 registerServiceProvider(new InputStreamImageInputStreamSpi()); 178 registerServiceProvider(new OutputStreamImageOutputStreamSpi()); 179 registerServiceProvider(new RAFImageInputStreamSpi()); 180 registerServiceProvider(new RAFImageOutputStreamSpi()); 181 182 registerInstalledProviders(); 183 } 184 185 /** 186 * Registers all available service providers found on the 187 * application class path, using the default 188 * {@code ClassLoader}. This method is typically invoked by 189 * the {@code ImageIO.scanForPlugins} method. 190 * 191 * @see javax.imageio.ImageIO#scanForPlugins 192 * @see ClassLoader#getResources 193 */ 194 public void registerApplicationClasspathSpis() { 195 // FIX: load only from application classpath 196 197 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 198 199 Iterator<Class<?>> categories = getCategories(); 200 while (categories.hasNext()) { 201 @SuppressWarnings("unchecked") 202 Class<IIOServiceProvider> c = (Class<IIOServiceProvider>)categories.next(); 203 Iterator<IIOServiceProvider> riter = 204 ServiceLoader.load(c, loader).iterator(); 205 while (riter.hasNext()) { 206 try { 207 // Note that the next() call is required to be inside 208 // the try/catch block; see 6342404. 209 IIOServiceProvider r = riter.next(); |