Save This Page
Home » openjdk-7 » javax » imageio » spi » [javadoc | source]
    1   /*
    2    * Copyright 1999-2007 Sun Microsystems, Inc.  All Rights Reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Sun designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Sun in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
   22    * CA 95054 USA or visit www.sun.com if you need additional information or
   23    * have any questions.
   24    */
   25   
   26   package javax.imageio.spi;
   27   
   28   import java.security.PrivilegedAction;
   29   import java.security.AccessController;
   30   import java.util.HashMap;
   31   import java.util.Iterator;
   32   import java.util.Map;
   33   import java.util.NoSuchElementException;
   34   import java.util.Set;
   35   import java.util.Vector;
   36   import com.sun.imageio.spi.FileImageInputStreamSpi;
   37   import com.sun.imageio.spi.FileImageOutputStreamSpi;
   38   import com.sun.imageio.spi.InputStreamImageInputStreamSpi;
   39   import com.sun.imageio.spi.OutputStreamImageOutputStreamSpi;
   40   import com.sun.imageio.spi.RAFImageInputStreamSpi;
   41   import com.sun.imageio.spi.RAFImageOutputStreamSpi;
   42   import com.sun.imageio.plugins.gif.GIFImageReaderSpi;
   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    * <p> Service providers found on the system classpath (<i>e.g.</i>,
   68    * the <code>jre/lib/ext</code> directory in Sun's implementation of
   69    * JDK) are automatically loaded as soon as this class is
   70    * instantiated.
   71    *
   72    * <p> When the <code>registerApplicationClasspathSpis</code> method
   73    * is called, service provider instances declared in the
   74    * meta-information section of JAR files on the application class path
   75    * are loaded.  To declare a service provider, a <code>services</code>
   76    * subdirectory is placed within the <code>META-INF</code> directory
   77    * that is present in every JAR file.  This directory contains a file
   78    * for each service provider interface that has one or more
   79    * implementation classes present in the JAR file.  For example, if
   80    * the JAR file contained a class named
   81    * <code>com.mycompany.imageio.MyFormatReaderSpi</code> which
   82    * implements the <code>ImageReaderSpi</code> interface, the JAR file
   83    * would contain a file named:
   84    *
   85    * <pre>
   86    * META-INF/services/javax.imageio.spi.ImageReaderSpi
   87    * </pre>
   88    *
   89    * containing the line:
   90    *
   91    * <pre>
   92    * com.mycompany.imageio.MyFormatReaderSpi
   93    * </pre>
   94    *
   95    * <p> The service provider classes are intended to be lightweight
   96    * and quick to load.  Implementations of these interfaces
   97    * should avoid complex dependencies on other classes and on
   98    * native code.
   99    *
  100    * <p> It is also possible to manually add service providers not found
  101    * automatically, as well as to remove those that are using the
  102    * interfaces of the <code>ServiceRegistry</code> class.  Thus
  103    * the application may customize the contents of the registry as it
  104    * sees fit.
  105    *
  106    * <p> For more details on declaring service providers, and the JAR
  107    * format in general, see the <a
  108    * href="{@docRoot}/../technotes/guides/jar/jar.html">
  109    * JAR File Specification</a>.
  110    *
  111    */
  112   public final class IIORegistry extends ServiceRegistry {
  113   
  114       /**
  115        * A <code>Vector</code> containing the valid IIO registry
  116        * categories (superinterfaces) to be used in the constructor.
  117        */
  118       private static final Vector initialCategories = new Vector(5);
  119   
  120       static {
  121           initialCategories.add(ImageReaderSpi.class);
  122           initialCategories.add(ImageWriterSpi.class);
  123           initialCategories.add(ImageTranscoderSpi.class);
  124           initialCategories.add(ImageInputStreamSpi.class);
  125           initialCategories.add(ImageOutputStreamSpi.class);
  126       }
  127   
  128       /**
  129        * Set up the valid service provider categories and automatically
  130        * register all available service providers.
  131        *
  132        * <p> The constructor is private in order to prevent creation of
  133        * additional instances.
  134        */
  135       private IIORegistry() {
  136           super(initialCategories.iterator());
  137           registerStandardSpis();
  138           registerApplicationClasspathSpis();
  139       }
  140   
  141       /**
  142        * Returns the default <code>IIORegistry</code> instance used by
  143        * the Image I/O API.  This instance should be used for all
  144        * registry functions.
  145        *
  146        * <p> Each <code>ThreadGroup</code> will receive its own
  147        * instance; this allows different <code>Applet</code>s in the
  148        * same browser (for example) to each have their own registry.
  149        *
  150        * @return the default registry for the current
  151        * <code>ThreadGroup</code>.
  152        */
  153       public static IIORegistry getDefaultInstance() {
  154           AppContext context = AppContext.getAppContext();
  155           IIORegistry registry =
  156               (IIORegistry)context.get(IIORegistry.class);
  157           if (registry == null) {
  158               // Create an instance for this AppContext
  159               registry = new IIORegistry();
  160               context.put(IIORegistry.class, registry);
  161           }
  162           return registry;
  163       }
  164   
  165       private void registerStandardSpis() {
  166           // Hardwire standard SPIs
  167           registerServiceProvider(new GIFImageReaderSpi());
  168           registerServiceProvider(new GIFImageWriterSpi());
  169           registerServiceProvider(new BMPImageReaderSpi());
  170           registerServiceProvider(new BMPImageWriterSpi());
  171           registerServiceProvider(new WBMPImageReaderSpi());
  172           registerServiceProvider(new WBMPImageWriterSpi());
  173           registerServiceProvider(new PNGImageReaderSpi());
  174           registerServiceProvider(new PNGImageWriterSpi());
  175           registerServiceProvider(new JPEGImageReaderSpi());
  176           registerServiceProvider(new JPEGImageWriterSpi());
  177           registerServiceProvider(new FileImageInputStreamSpi());
  178           registerServiceProvider(new FileImageOutputStreamSpi());
  179           registerServiceProvider(new InputStreamImageInputStreamSpi());
  180           registerServiceProvider(new OutputStreamImageOutputStreamSpi());
  181           registerServiceProvider(new RAFImageInputStreamSpi());
  182           registerServiceProvider(new RAFImageOutputStreamSpi());
  183   
  184           registerInstalledProviders();
  185       }
  186   
  187       /**
  188        * Registers all available service providers found on the
  189        * application class path, using the default
  190        * <code>ClassLoader</code>.  This method is typically invoked by
  191        * the <code>ImageIO.scanForPlugins</code> method.
  192        *
  193        * @see javax.imageio.ImageIO#scanForPlugins
  194        * @see ClassLoader#getResources
  195        */
  196       public void registerApplicationClasspathSpis() {
  197           // FIX: load only from application classpath
  198   
  199           ClassLoader loader = Thread.currentThread().getContextClassLoader();
  200   
  201           Iterator categories = getCategories();
  202           while (categories.hasNext()) {
  203               Class<IIOServiceProvider> c = (Class)categories.next();
  204               Iterator<IIOServiceProvider> riter =
  205                       ServiceLoader.load(c, loader).iterator();
  206               while (riter.hasNext()) {
  207                   try {
  208                       // Note that the next() call is required to be inside
  209                       // the try/catch block; see 6342404.
  210                       IIOServiceProvider r = riter.next();
  211                       registerServiceProvider(r);
  212                   } catch (ServiceConfigurationError err) {
  213                       if (System.getSecurityManager() != null) {
  214                           // In the applet case, we will catch the  error so
  215                           // registration of other plugins can  proceed
  216                           err.printStackTrace();
  217                       } else {
  218                           // In the application case, we will  throw the
  219                           // error to indicate app/system  misconfiguration
  220                           throw err;
  221                       }
  222                   }
  223               }
  224           }
  225       }
  226   
  227       private void registerInstalledProviders() {
  228           /*
  229             We need load installed providers from lib/ext
  230             directory in the privileged mode in order to
  231             be able read corresponding jar files even if
  232             file read capability is restricted (like the
  233             applet context case).
  234            */
  235           PrivilegedAction doRegistration =
  236               new PrivilegedAction() {
  237                   public Object run() {
  238                       Iterator categories = getCategories();
  239                       while (categories.hasNext()) {
  240                           Class<IIOServiceProvider> c = (Class)categories.next();
  241                           for (IIOServiceProvider p : ServiceLoader.loadInstalled(c)) {
  242                               registerServiceProvider(p);
  243                           }
  244                       }
  245                       return this;
  246                   }
  247               };
  248   
  249           AccessController.doPrivileged(doRegistration);
  250       }
  251   }

Save This Page
Home » openjdk-7 » javax » imageio » spi » [javadoc | source]