diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/javax/imageio/spi | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/javax/imageio/spi')
11 files changed, 2509 insertions, 0 deletions
diff --git a/libjava/classpath/javax/imageio/spi/IIORegistry.java b/libjava/classpath/javax/imageio/spi/IIORegistry.java new file mode 100644 index 000000000..faa571d60 --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/IIORegistry.java @@ -0,0 +1,119 @@ +/* IIORegistry.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import gnu.classpath.ServiceFactory; + +import java.awt.Toolkit; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; + +import gnu.java.awt.ClasspathToolkit; +import gnu.javax.imageio.bmp.BMPImageReaderSpi; +import gnu.javax.imageio.bmp.BMPImageWriterSpi; +import gnu.javax.imageio.gif.GIFImageReaderSpi; +import gnu.javax.imageio.png.PNGImageReaderSpi; + +public final class IIORegistry extends ServiceRegistry +{ + private static final HashSet defaultCategories = new HashSet(); + + private static HashMap instances = new HashMap(); + + static + { + defaultCategories.add(ImageReaderSpi.class); + defaultCategories.add(ImageWriterSpi.class); + defaultCategories.add(ImageTranscoderSpi.class); + defaultCategories.add(ImageInputStreamSpi.class); + defaultCategories.add(ImageOutputStreamSpi.class); + } + + public static synchronized IIORegistry getDefaultInstance() + { + // XXX: This leaks memory if a ThreadGroup isn't available anymore. + ThreadGroup group = Thread.currentThread().getThreadGroup(); + IIORegistry registry = (IIORegistry) instances.get(group); + + if (registry == null) + { + registry = new IIORegistry(); + instances.put(group, registry); + } + + return registry; + } + + private IIORegistry() + { + super(defaultCategories.iterator()); + + // XXX: Register built-in Spis here. + registerServiceProvider(new PNGImageReaderSpi()); // Register PNG decoder. + registerServiceProvider(new GIFImageReaderSpi()); // Register GIF decoder. + registerServiceProvider(new BMPImageReaderSpi()); + registerServiceProvider(new BMPImageWriterSpi()); + + Toolkit toolkit = Toolkit.getDefaultToolkit(); + if (toolkit instanceof ClasspathToolkit) + ((ClasspathToolkit)toolkit).registerImageIOSpis(this); + + registerApplicationClasspathSpis(); + } + + /** + * Registers all available service providers found on the application + * classpath. + */ + public void registerApplicationClasspathSpis() + { + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + Iterator categories = getCategories(); + + while (categories.hasNext()) + { + Class category = (Class) categories.next(); + Iterator providers = ServiceFactory.lookupProviders(category, loader); + + while (providers.hasNext()) + registerServiceProvider((IIOServiceProvider) providers.next()); + } + } +} diff --git a/libjava/classpath/javax/imageio/spi/IIOServiceProvider.java b/libjava/classpath/javax/imageio/spi/IIOServiceProvider.java new file mode 100644 index 000000000..48fa7d414 --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/IIOServiceProvider.java @@ -0,0 +1,163 @@ +/* IIOServiceProvider.java -- General service provider for image I/O. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import java.util.Locale; + + +/** + * An abstract superclass for service providers that perform image I/O. + * + * @since 1.4 + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public abstract class IIOServiceProvider + implements RegisterableService +{ + /** + * The vendor of this service provider, or <code>null</code> if the + * subclass constructor did not set this field. + * + * @see #getVendorName() + */ + protected String vendorName; + + + /** + * The version of this service provider, or <code>null</code> if the + * subclass constructor did not set this field. + * + * @see #getVersion() + */ + protected String version; + + + /** + * Constructs a general <code>IIOServiceProvider</code>, given the + * vendor name and a version string. + * + * @throws IllegalArgumentException if <code>vendorName</code> + * or <code>version</code> is <code>null</code>. + */ + public IIOServiceProvider(String vendorName, String version) + { + if (vendorName == null || version == null) + throw new IllegalArgumentException(); + + this.vendorName = vendorName; + this.version = version; + } + + + /** + * Constructs a general <code>IIOServiceProvider</code> without + * specifying a vendor name and a version string. The subclass + * constructor should set the {@link #vendorName} and {@link + * #version} to non-null values. + */ + public IIOServiceProvider() + { + } + + + /** + * Informs this service provider that it has been registered in a + * {@link ServiceRegistry}. If this provider gets registered as an + * implementor for several service categories, its + * <code>onRegistration</code> method will be called multiple times. + * The default implementation does nothing. + * + * @param registry the registry to which this service provider has + * been added. + * + * @param category the service category for which this provider has + * been registered as an implementor. + */ + public void onRegistration(ServiceRegistry registry, Class<?> category) + { + } + + + /** + * Informs this service provider that it has been de-registered from + * a {@link ServiceRegistry}. If this provider had been registered + * as an implementor for several service categories, its + * <code>onDeregistration</code> method will be called multiple + * times. The default implementation does nothing. + * + * @param registry the registry from which this service provider has + * been removed. + * + * @param category the service category for which this provider has + * been registered as an implementor. + */ + public void onDeregistration(ServiceRegistry registry, Class<?> category) + { + } + + + /** + * Returns the name of the vendor of this service provider. + */ + public String getVendorName() + { + return vendorName; + } + + + /** + * Returns an identifier string for the version of this service + * provider. + */ + public String getVersion() + { + return version; + } + + + /** + * Returns a short description of this service provider that can be + * presented to a human user. + * + * @param locale the locale for which the description string should + * be localized. + */ + public abstract String getDescription(Locale locale); +} diff --git a/libjava/classpath/javax/imageio/spi/ImageInputStreamSpi.java b/libjava/classpath/javax/imageio/spi/ImageInputStreamSpi.java new file mode 100644 index 000000000..2b60868a5 --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/ImageInputStreamSpi.java @@ -0,0 +1,144 @@ +/* ImageInputStreamSpi.java -- Service provider for image input streams. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import java.io.File; +import java.io.IOException; + +import javax.imageio.stream.ImageInputStream; + +/** + * An abstract superclass for service providers that create + * {@linkplain javax.imageio.stream.ImageInputStream image input + * streams} for a file, URL, byte array or any other source. + * + * @since 1.4 + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public abstract class ImageInputStreamSpi + extends IIOServiceProvider +{ + /** + * Indicates which kind of input is processable by the streams + * created by {@link #createInputStreamInstance(Object)}. + */ + protected Class<?> inputClass; + + + /** + * Constructs a service provider for image input streams, given no + * parameters. It is up to the sub-class to set {@link #vendorName}, + * {@link #version} and {@link #inputClass} to non-null values. + */ + protected ImageInputStreamSpi() + { + } + + + /** + * Constructs a service provider for image input streams, given the + * vendor name and a version string. + * + * @throws IllegalArgumentException if <code>vendorName</code> + * or <code>version</code> is <code>null</code>. + */ + public ImageInputStreamSpi(String vendorName, String version, + Class<?> inputClass) + { + super(vendorName, version); + this.inputClass = inputClass; + } + + + /** + * Determines which kind of input is processable by the streams + * created by {@link #createInputStreamInstance(Object)}. + */ + public Class<?> getInputClass() + { + return inputClass; + } + + + /** + * Determines whether <code>ImageInputStreams</code> created + * by this service provider benefit from using a cache file. + * + * <p>The default behavior is to return <code>false</code>. + * + * @return <code>true</code> if the created streams are faster or + * need less memory when a cache file is being used; + * <code>false</code> if no positive effect results from the cache + * file. + */ + public boolean canUseCacheFile() + { + return false; + } + + + /** + * Determines whether <code>ImageInputStreams</code> created + * by this service provider require the use of a cache file. + * + * <p>The default behavior is to return <code>false</code>. + * + * @return <code>true</code> if the created streams can only work + * when a cache file is being used; <code>false</code> if no cache + * file is needed. + */ + public boolean needsCacheFile() + { + return false; + } + + + public abstract ImageInputStream createInputStreamInstance(Object input, + boolean useCache, + File cacheDir) + throws IOException; + + + public ImageInputStream createInputStreamInstance(Object input) + throws IOException + { + return createInputStreamInstance(input, canUseCacheFile(), null); + } +} diff --git a/libjava/classpath/javax/imageio/spi/ImageOutputStreamSpi.java b/libjava/classpath/javax/imageio/spi/ImageOutputStreamSpi.java new file mode 100644 index 000000000..872e7181e --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/ImageOutputStreamSpi.java @@ -0,0 +1,143 @@ +/* ImageOutputStreamSpi.java -- Service provider for image output streams. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import java.io.File; +import java.io.IOException; + +import javax.imageio.stream.ImageOutputStream; + +/** + * An abstract superclass for service providers that create + * {@linkplain javax.imageio.stream.ImageOutputStream image output + * streams} for a file, URL, byte array or any other target. + * + * @since 1.4 + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public abstract class ImageOutputStreamSpi + extends IIOServiceProvider +{ + /** + * Indicates which kind of output is produced by the streams + * created by {@link #createOutputStreamInstance(Object)}. + */ + protected Class<?> outputClass; + + + /** + * Constructs a service provider for image output streams, given no + * parameters. It is up to the sub-class to set {@link #vendorName}, + * {@link #version} and {@link #outputClass} to non-null values. + */ + protected ImageOutputStreamSpi() + { + } + + + /** + * Constructs a service provider for image output streams, given the + * vendor name, a version string and the kind of producable output. + * + * @throws IllegalArgumentException if <code>vendorName</code> + * or <code>version</code> is <code>null</code>. + */ + public ImageOutputStreamSpi(String vendorName, String version, + Class<?> outputClass) + { + super(vendorName, version); + this.outputClass = outputClass; + } + + + /** + * Determines which kind of output is produced by the streams + * created by {@link #createOutputStreamInstance(Object)}. + */ + public Class<?> getOutputClass() + { + return outputClass; + } + + + /** + * Determines whether <code>ImageOutputStreams</code> created + * by this service provider benefit from using a cache file. + * + * <p>The default behavior is to return <code>false</code>. + * + * @return <code>true</code> if the created streams are faster or + * need less memory when a cache file is being used; + * <code>false</code> if no positive effect results from the cache + * file. + */ + public boolean canUseCacheFile() + { + return false; + } + + + /** + * Determines whether <code>ImageOutputStreams</code> created + * by this service provider require the use of a cache file. + * + * <p>The default behavior is to return <code>false</code>. + * + * @return <code>true</code> if the created streams can only work + * when a cache file is being used; <code>false</code> if no cache + * file is needed. + */ + public boolean needsCacheFile() + { + return false; + } + + + public abstract ImageOutputStream createOutputStreamInstance( + Object output, boolean useCache, File cacheDir) + throws IOException; + + + public ImageOutputStream createOutputStreamInstance(Object output) + throws IOException + { + return createOutputStreamInstance(output, canUseCacheFile(), null); + } +} diff --git a/libjava/classpath/javax/imageio/spi/ImageReaderSpi.java b/libjava/classpath/javax/imageio/spi/ImageReaderSpi.java new file mode 100644 index 000000000..3ffa93a0b --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/ImageReaderSpi.java @@ -0,0 +1,121 @@ +/* ImageReaderSpi.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import java.io.IOException; + +import javax.imageio.ImageReader; +import javax.imageio.stream.ImageInputStream; + +/** + * @author Michael Koch (konqueror@gmx.de) + */ +public abstract class ImageReaderSpi extends ImageReaderWriterSpi +{ + public static final Class[] STANDARD_INPUT_TYPE = + { ImageInputStream.class }; + + protected Class[] inputTypes; + protected String[] writerSpiNames; + + protected ImageReaderSpi() + { + // Do nothing here. + } + + public ImageReaderSpi(String vendorName, String version, String[] names, + String[] suffixes, String[] MIMETypes, + String readerClassName, Class[] inputTypes, + String[] writerSpiNames, + boolean supportsStandardStreamMetadataFormat, + String nativeStreamMetadataFormatName, + String nativeStreamMetadataFormatClassName, + String[] extraStreamMetadataFormatNames, + String[] extraStreamMetadataFormatClassNames, + boolean supportsStandardImageMetadataFormat, + String nativeImageMetadataFormatName, + String nativeImageMetadataFormatClassName, + String[] extraImageMetadataFormatNames, + String[] extraImageMetadataFormatClassNames) + { + super(vendorName, version, names, suffixes, MIMETypes, readerClassName, + supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName, + nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames, + extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat, + nativeImageMetadataFormatName, nativeImageMetadataFormatClassName, + extraImageMetadataFormatNames, extraImageMetadataFormatClassNames); + + if (inputTypes == null + || inputTypes.length == 0) + throw new IllegalArgumentException("inputTypes may not be null or empty"); + + this.inputTypes = inputTypes; + this.writerSpiNames = writerSpiNames; + } + + public abstract boolean canDecodeInput(Object source) + throws IOException; + + public ImageReader createReaderInstance() + throws IOException + { + return createReaderInstance(null); + } + + public abstract ImageReader createReaderInstance(Object extension) + throws IOException; + + public String[] getImageWriterSpiNames() + { + return writerSpiNames; + } + + public Class[] getInputTypes() + { + return inputTypes; + } + + public boolean isOwnReader(ImageReader reader) + { + if (reader == null) + throw new IllegalArgumentException("reader may not be null"); + + return pluginClassName.equals(reader.getClass().getName()); + } +} diff --git a/libjava/classpath/javax/imageio/spi/ImageReaderWriterSpi.java b/libjava/classpath/javax/imageio/spi/ImageReaderWriterSpi.java new file mode 100644 index 000000000..40d44e3d0 --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/ImageReaderWriterSpi.java @@ -0,0 +1,511 @@ +/* ImageReaderWriterSpi.java -- Superclass for image reader and writer spis. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import javax.imageio.metadata.IIOMetadataFormat; +import javax.imageio.metadata.IIOMetadataFormatImpl; + +/** + * An abstract superclass that contains the common parts of {@link + * javax.imageio.spi.ImageReaderSpi} and {@link + * javax.imageio.spi.ImageWriterSpi}. + * + * @since 1.4 + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public abstract class ImageReaderWriterSpi + extends IIOServiceProvider +{ + /** + * The human-readable, localized names of the supported image + * formats. This value should be non-<code>null</code> after + * construction. + * + * @see #getFormatNames() + */ + protected String[] names; + + + /** + * The file suffixes of the supported image formats. This value + * should be non-<code>null</code> after construction. + * + * @see #getFileSuffixes() + */ + protected String[] suffixes; + + + /** + * The MIME types of the supported image formats. This value + * should be non-<code>null</code> after construction. + * + * @see #getMIMETypes() + */ + protected String[] MIMETypes; + + + /** + * The fully qualified name of the class that implements the {@link + * javax.imageio.ImageReader} or {@link javax.imageio.ImageWriter} + * interface. This value should be non-<code>null</code> after + * construction. + * + * @see #getPluginClassName() + */ + protected String pluginClassName; + + + /** + * Indicates whether the per-stream {@linkplain + * javax.imageio.metadata.IIOMetadata metadata objects} associated + * with this plug-in support format + * <code>“javax_imageio_1.0”</code> in their + * <code>getAsTree</code> and <code>setAsTree</code> methods. + * + * @see #isStandardStreamMetadataFormatSupported() + */ + protected boolean supportsStandardStreamMetadataFormat; + + + /** + * The name of the format that allows encoding all stream metadata + * without loss, or <code>null</code> if this plug-in does not + * provide a format that preserves all stream metadata. + */ + protected String nativeStreamMetadataFormatName; + + protected String nativeStreamMetadataFormatClassName; + + + /** + * The names of additional formats for encoding stream metadata, + * other than the {@linkplain + * #isStandardStreamMetadataFormatSupported() standard} and the + * {@linkplain #getNativeStreamMetadataFormatName() native} formats, + * or <code>null</code> if this plug-in does not provide any extra + * formats. + */ + protected String[] extraStreamMetadataFormatNames; + + + protected String[] extraStreamMetadataFormatClassNames; + + + /** + * Indicates whether the per-image {@linkplain + * javax.imageio.metadata.IIOMetadata metadata objects} associated + * with this plug-in support format + * <code>“javax_imageio_1.0”</code> in their + * <code>getAsTree</code> and <code>setAsTree</code> methods. + * + * @see #isStandardImageMetadataFormatSupported() + */ + protected boolean supportsStandardImageMetadataFormat; + + + /** + * The name of the format that allows encoding all image metadata + * without loss, or <code>null</code> if this plug-in does not + * provide a format that preserves all image metadata. + */ + protected String nativeImageMetadataFormatName; + + protected String nativeImageMetadataFormatClassName; + + + /** + * The names of additional formats for encoding image metadata, + * other than the {@linkplain + * #isStandardImageMetadataFormatSupported() standard} and the + * {@linkplain #getNativeImageMetadataFormatName() native} formats, + * or <code>null</code> if this plug-in does not provide any extra + * formats. + */ + protected String[] extraImageMetadataFormatNames; + + + protected String[] extraImageMetadataFormatClassNames; + + + /** + * Constructs an <code>ImageReaderWriteSpi</code> instance, without + * specifying a number of parameters. Constructors of concrete + * subclasses must ensure that they set all inherited fields to + * meaningful values. + */ + public ImageReaderWriterSpi() + { + } + + + /** + * Constructs an <code>ImageReaderWriteSpi</code> instance, + * specifying a number of parameters. + * + * @param names the human-readable, localized names of the supported + * image formats, for example <code>[“Tagged Image File + * Format”, “Portable Network + * Graphics”]</code>. + * + * @param suffixes the file suffixes of the supported image formats, + * for example <code>[“tiff”, “tif”, + * “png”]</code>. + * + * @param MIMETypes the MIME types of the supported image formats, + * for example <code>[“image/tiff”, + * “image/png”]</code>. + * + * @param pluginClassName the fully qualified name of the class that + * implements the {@link javax.imageio.ImageReader} or {@link + * javax.imageio.ImageWriter} interface. + * + * @param supportsStandardStreamMetadataFormat whether the + * per-stream {@linkplain javax.imageio.metadata.IIOMetadata + * metadata objects} associated with this plug-in support format + * <code>“javax_imageio_1.0”</code> in their + * <code>getAsTree</code> and <code>setAsTree</code> methods. + * + * @param nativeStreamMetadataFormatName the name of the format that + * allows encoding all stream metadata without loss, or + * <code>null</code> if this plug-in does not provide a format that + * preserves all stream metadata. + * + * @param extraStreamMetadataFormatNames the names of additional + * formats for encoding stream metadata, other than the {@linkplain + * #isStandardStreamMetadataFormatSupported() standard} and the + * {@linkplain #getNativeStreamMetadataFormatName() native} formats, + * or <code>null</code> if this plug-in does not provide any extra + * formats. + * + * @param supportsStandardImageMetadataFormat whether the per-image + * {@linkplain javax.imageio.metadata.IIOMetadata metadata objects} + * associated with this plug-in support format + * <code>“javax_imageio_1.0”</code> in their + * <code>getAsTree</code> and <code>setAsTree</code> methods. + * + * @param nativeImageMetadataFormatName the name of the format that + * allows encoding all image metadata without loss, or + * <code>null</code> if this plug-in does not provide a format that + * preserves all image metadata. + * + * @param extraImageMetadataFormatNames the names of additional + * formats for encoding image metadata, other than the {@linkplain + * #isStandardImageMetadataFormatSupported() standard} and the + * {@linkplain #getNativeImageMetadataFormatName() native} formats, + * or <code>null</code> if this plug-in does not provide any extra + * formats. + * + * @throws IllegalArgumentException if <code>vendorName</code> + * or <code>version</code> is <code>null</code>. + */ + public ImageReaderWriterSpi(String vendorName, String version, + String[] names, String[] suffixes, + String[] MIMETypes, String pluginClassName, + boolean supportsStandardStreamMetadataFormat, + String nativeStreamMetadataFormatName, + String nativeStreamMetadataFormatClassName, + String[] extraStreamMetadataFormatNames, + String[] extraStreamMetadataFormatClassNames, + boolean supportsStandardImageMetadataFormat, + String nativeImageMetadataFormatName, + String nativeImageMetadataFormatClassName, + String[] extraImageMetadataFormatNames, + String[] extraImageMetadataFormatClassNames) + { + /* The inherited constructor will throw IllegalArgumentException + * if one of its arguments is null. + */ + super(vendorName, version); + + if (names == null || names.length == 0 || pluginClassName == null) + throw new IllegalArgumentException(); + + this.names = names; + this.suffixes = suffixes; + this.MIMETypes = MIMETypes; + this.pluginClassName = pluginClassName; + + this.supportsStandardStreamMetadataFormat + = supportsStandardStreamMetadataFormat; + + this.nativeStreamMetadataFormatName + = nativeStreamMetadataFormatName; + + this.nativeStreamMetadataFormatClassName + = nativeStreamMetadataFormatClassName; + + this.extraStreamMetadataFormatNames + = extraStreamMetadataFormatNames; + + this.extraStreamMetadataFormatClassNames + = extraStreamMetadataFormatClassNames; + + this.supportsStandardImageMetadataFormat + = supportsStandardImageMetadataFormat; + + this.nativeImageMetadataFormatName + = nativeImageMetadataFormatName; + + this.nativeImageMetadataFormatClassName + = nativeImageMetadataFormatClassName; + + this.extraImageMetadataFormatNames + = extraImageMetadataFormatNames; + + this.extraImageMetadataFormatClassNames + = extraImageMetadataFormatClassNames; + } + + + /** + * Returns the human-readable, localized names of the supported + * image formats. For example, a plug-in might return an array with + * the elements <code>[“Tagged Image File Format”, + * “Portable Network Graphics”]</code>. + */ + public String[] getFormatNames() + { + return (String[]) names.clone(); + } + + + /** + * Returns the file suffixes of the supported image formats, for + * example <code>[“tiff”, “tif”, + * “png”]</code>. + */ + public String[] getFileSuffixes() + { + return suffixes; + } + + + /** + * Returns the MIME types of the supported image formats, for + * example <code>[“image/tiff”, + * “image/png”]</code>. + * + * @return an array of MIME type strings, or <code>null</code> if + * none of the supported formats has an associated MIME type. + */ + public String[] getMIMETypes() + { + return MIMETypes; + } + + + /** + * Returns the fully qualified name of the class that implements the + * {@link javax.imageio.ImageReader} or {@link + * javax.imageio.ImageWriter} interface. + */ + public String getPluginClassName() + { + return pluginClassName; + } + + + /** + * Returns whether the per-stream {@linkplain + * javax.imageio.metadata.IIOMetadata metadata objects} associated + * with this plug-in support format + * <code>“javax_imageio_1.0”</code> in their + * <code>getAsTree</code> and <code>setAsTree</code> methods. + */ + public boolean isStandardStreamMetadataFormatSupported() + { + return supportsStandardStreamMetadataFormat; + } + + + /** + * Returns the name of the format that allows encoding all stream + * metadata without loss, or <code>null</code> if this plug-in does + * not provide a format that preserves all stream metadata. + * + * @see #getNativeImageMetadataFormatName() + */ + public String getNativeStreamMetadataFormatName() + { + return nativeStreamMetadataFormatName; + } + + + /** + * Returns the names of additional formats for encoding stream + * metadata, other than the {@linkplain + * #isStandardStreamMetadataFormatSupported() standard} and the + * {@linkplain #getNativeStreamMetadataFormatName() native} formats, + * or <code>null</code> if this plug-in does not provide any extra + * formats. + * + * @see #getExtraImageMetadataFormatNames() + */ + public String[] getExtraStreamMetadataFormatNames() + { + return extraStreamMetadataFormatNames; + } + + + /** + * Returns whether the per-image {@linkplain + * javax.imageio.metadata.IIOMetadata metadata objects} associated + * with this plug-in support format + * <code>“javax_imageio_1.0”</code> in their + * <code>getAsTree</code> and <code>setAsTree</code> methods. + */ + public boolean isStandardImageMetadataFormatSupported() + { + return supportsStandardImageMetadataFormat; + } + + + /** + * Returns the name of the format that allows encoding all image + * metadata without loss, or <code>null</code> if this plug-in does + * not provide a format that preserves all image metadata. + * + * @see #getNativeStreamMetadataFormatName() + */ + public String getNativeImageMetadataFormatName() + { + return nativeImageMetadataFormatName; + } + + + /** + * Returns the names of additional formats for encoding image + * metadata, other than the {@linkplain + * #isStandardImageMetadataFormatSupported() standard} and the + * {@linkplain #getNativeImageMetadataFormatName() native} formats, + * or <code>null</code> if this plug-in does not provide any extra + * formats. + * + * @see #getExtraStreamMetadataFormatNames() + */ + public String[] getExtraImageMetadataFormatNames() + { + return extraImageMetadataFormatNames; + } + + /** + * Returns an IIOMetadataFormat object that represents the requested + * stream metadata format or null if the given format is supported + * but no IIOMetadataFormat can be created for it. + * + * @param formatName the requested stream metadata format name + * + * @return an IIOMetadataFormat object or null + * + * @throws IllegalArgumentException if formatName is null or is not + * one of the standard metadata format or this provider's native or + * extra stream metadata formats + */ + public IIOMetadataFormat getStreamMetadataFormat (String formatName) + { + if (formatName == null) + throw new IllegalArgumentException ("null stream metadata format name"); + + if (!formatName.equals (getNativeStreamMetadataFormatName()) + && !formatName.equals (IIOMetadataFormatImpl.standardMetadataFormatName)) + { + String[] extraNames = getExtraStreamMetadataFormatNames (); + boolean foundName = false; + for (int i = 0; i < extraNames.length; i++) + { + if (formatName.equals(extraNames[i])) + { + foundName = true; + break; + } + } + if (!foundName) + throw new IllegalArgumentException ("unsupported stream metadata format name"); + } + + if (formatName.equals (IIOMetadataFormatImpl.standardMetadataFormatName)) + return IIOMetadataFormatImpl.getStandardFormatInstance (); + else + // Default implementation returns null. + return null; + } + + /** + * Returns an IIOMetadataFormat object that represents the requested + * image metadata format or null if the given format is supported + * but no IIOMetadataFormat can be created for it. + * + * @param formatName the requested image metadata format name + * + * @return an IIOMetadataFormat object or null + * + * @throws IllegalArgumentException if formatName is null or is not + * one of the standard metadata format or this provider's native or + * extra image metadata formats + */ + public IIOMetadataFormat getImageMetadataFormat (String formatName) + { + if (formatName == null) + throw new IllegalArgumentException ("null image metadata format name"); + + if (!formatName.equals (getNativeImageMetadataFormatName()) + && !formatName.equals (IIOMetadataFormatImpl.standardMetadataFormatName)) + { + String[] extraNames = getExtraImageMetadataFormatNames (); + boolean foundName = false; + for (int i = 0; i < extraNames.length; i++) + { + if (formatName.equals(extraNames[i])) + { + foundName = true; + break; + } + } + if (!foundName) + throw new IllegalArgumentException ("unsupported image metadata format name"); + } + + if (formatName.equals (IIOMetadataFormatImpl.standardMetadataFormatName)) + return IIOMetadataFormatImpl.getStandardFormatInstance (); + else + // Default implementation returns null. + return null; + } +} diff --git a/libjava/classpath/javax/imageio/spi/ImageTranscoderSpi.java b/libjava/classpath/javax/imageio/spi/ImageTranscoderSpi.java new file mode 100644 index 000000000..1c04ad20c --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/ImageTranscoderSpi.java @@ -0,0 +1,84 @@ +/* ImageTranscoderSpi.java -- Factory for image metadata transcoders. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import javax.imageio.ImageTranscoder; + + +/** + * An abstract superclass for service providers that create + * {@linkplain javax.imageio.ImageTranscoder image metadata + * transcoders}. + * + * @since 1.4 + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public abstract class ImageTranscoderSpi + extends IIOServiceProvider +{ + /** + * Constructs a service provider for image metadata transcoders, + * given no parameters. It is up to the sub-class to set {@link + * #vendorName} and {@link #version} to non-null values. + */ + protected ImageTranscoderSpi() + { + } + + + /** + * Constructs a service provider for image metadata transcoders, + * given the vendor name and a version string. + * + * @throws IllegalArgumentException if <code>vendorName</code> + * or <code>version</code> is <code>null</code>. + */ + public ImageTranscoderSpi(String vendorName, String version) + { + super(vendorName, version); + } + + + public abstract String getReaderServiceProviderName(); + + public abstract String getWriterServiceProviderName(); + + public abstract ImageTranscoder createTranscoderInstance(); +} diff --git a/libjava/classpath/javax/imageio/spi/ImageWriterSpi.java b/libjava/classpath/javax/imageio/spi/ImageWriterSpi.java new file mode 100644 index 000000000..6a07348cf --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/ImageWriterSpi.java @@ -0,0 +1,135 @@ +/* ImageWriterSpi.java -- + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import java.awt.image.RenderedImage; +import java.io.IOException; + +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageOutputStream; + +/** + * @author Michael Koch (konqueror@gmx.de) + */ +public abstract class ImageWriterSpi extends ImageReaderWriterSpi +{ + public static final Class[] STANDARD_OUTPUT_TYPE = + { ImageOutputStream.class }; + + protected Class[] outputTypes; + protected String[] readerSpiNames; + + protected ImageWriterSpi() + { + // Do nothing here. + } + + public ImageWriterSpi(String vendorName, String version, String[] names, + String[] suffixes, String[] MIMETypes, + String writerClassName, Class[] outputTypes, + String[] readerSpiNames, + boolean supportsStandardStreamMetadataFormat, + String nativeStreamMetadataFormatName, + String nativeStreamMetadataFormatClassName, + String[] extraStreamMetadataFormatNames, + String[] extraStreamMetadataFormatClassNames, + boolean supportsStandardImageMetadataFormat, + String nativeImageMetadataFormatName, + String nativeImageMetadataFormatClassName, + String[] extraImageMetadataFormatNames, + String[] extraImageMetadataFormatClassNames) + { + super(vendorName, version, names, suffixes, MIMETypes, writerClassName, + supportsStandardStreamMetadataFormat, nativeStreamMetadataFormatName, + nativeStreamMetadataFormatClassName, extraStreamMetadataFormatNames, + extraStreamMetadataFormatClassNames, supportsStandardImageMetadataFormat, + nativeImageMetadataFormatName, nativeImageMetadataFormatClassName, + extraImageMetadataFormatNames, extraImageMetadataFormatClassNames); + + if (writerClassName == null) + throw new IllegalArgumentException("writerClassName is null"); + + if (outputTypes == null + || outputTypes.length == 0) + throw new IllegalArgumentException("outputTypes may not be null or empty"); + + this.outputTypes = outputTypes; + this.readerSpiNames = readerSpiNames; + } + + public abstract boolean canEncodeImage(ImageTypeSpecifier type); + + public boolean canEncodeImage(RenderedImage image) + { + return canEncodeImage (new ImageTypeSpecifier(image)); + } + + public ImageWriter createWriterInstance() + throws IOException + { + return createWriterInstance(null); + } + + public abstract ImageWriter createWriterInstance(Object extension) + throws IOException; + + public String[] getImageReaderSpiNames() + { + return readerSpiNames; + } + + public Class[] getOutputTypes() + { + return outputTypes; + } + + public boolean isFormatLossless() + { + return true; + } + + public boolean isOwnWriter(ImageWriter writer) + { + if (writer == null) + throw new IllegalArgumentException("writer may not be null"); + + return pluginClassName.equals(writer.getClass().getName()); + } +} diff --git a/libjava/classpath/javax/imageio/spi/RegisterableService.java b/libjava/classpath/javax/imageio/spi/RegisterableService.java new file mode 100644 index 000000000..b424e04a3 --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/RegisterableService.java @@ -0,0 +1,82 @@ +/* RegisterableService.java -- An interface for service providers. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + + +/** + * An interface which service providers may optionally implement in + * order to get notified when they are added or removed from a {@link + * ServiceRegistry}. + * + * @since 1.4 + * + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public interface RegisterableService +{ + /** + * Informs this service provider that it has been registered in a + * {@link ServiceRegistry}. If this provider gets registered as an + * implementor for several service categories, its + * <code>onRegistration</code> method will be called multiple times. + * + * @param registry the registry to which this service provider has + * been added. + * + * @param category the service category for which this provider has + * been registered as an implementor. + */ + void onRegistration(ServiceRegistry registry, Class<?> category); + + + /** + * Informs this service provider that it has been de-registered from + * a {@link ServiceRegistry}. If this provider had been registered + * as an implementor for several service categories, its + * <code>onDeregistration</code> method will be called multiple + * times. + * + * @param registry the registry from which this service provider has + * been removed. + * + * @param category the service category for which this provider has + * been registered as an implementor. + */ + void onDeregistration(ServiceRegistry registry, Class<?> category); +} diff --git a/libjava/classpath/javax/imageio/spi/ServiceRegistry.java b/libjava/classpath/javax/imageio/spi/ServiceRegistry.java new file mode 100644 index 000000000..d92359688 --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/ServiceRegistry.java @@ -0,0 +1,961 @@ +/* ServiceRegistry.java -- A simple registry for service providers. + Copyright (C) 2004, 2005 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package javax.imageio.spi; + +import gnu.classpath.ServiceFactory; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashSet; +import java.util.IdentityHashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +/** + * A registry for service providers. + * + * @since 1.4 + * + * @author Michael Koch (konqueror@gmx.de) + * @author Sascha Brawer (brawer@dandelis.ch) + */ +public class ServiceRegistry +{ + // Package-private to avoid a trampoline. + /** + * The service categories of this registry. + * + * <p>Note that we expect that only very few categories will + * typically be used with a registry. The most common case will be + * one, it seems unlikely that any registry would contain more than + * five or six categories. Therefore, we intentionally avoid the + * overhead of a HashMap. + * + * @see #providers + */ + final Class[] categories; + + + /** + * The registered providers for each service category, indexed by + * the same index as the {@link #categories} array. If no provider + * is registered for a category, the array entry will be + * <code>null</code>. + * + * <p>Note that we expect that only very few providers will + * typically be registered for a category. The most common case will + * be one or two. Therefore, we intentionally avoid the overhead of + * a HashMap. + */ + private final LinkedList[] providers; + + + /** + * The ordring constaints for each service category, indexed by the + * same index as the {@link #categories} array. The constraints for + * a service category are stored as a <code>Map<Object, + * Set<Object>></code>, where the Map’s values are + * those providers that need to come after the key. If no + * constraints are imposed on the providers of a category, the array + * entry will be <code>null</code>. If no constraints have been set + * whatsoever, <code>constraints</code> will be <code>null</code>. + * + * <p>Note that we expect that only very few constraints will + * typically be imposed on a category. The most common case will + * be zero. + */ + private IdentityHashMap[] constraints; + + + /** + * Constructs a <code>ServiceRegistry</code> for the specified + * service categories. + * + * @param categories the categories to support + * + * @throws IllegalArgumentException if <code>categories</code> is + * <code>null</code>, or if its {@link Iterator#next()} method + * returns <code>null</code>. + * + * @throws ClassCastException if <code>categories</code> does not + * iterate over instances of {@link java.lang.Class}. + */ + public ServiceRegistry(Iterator<Class<?>> categories) + { + ArrayList cats = new ArrayList(/* expected size */ 10); + + if (categories == null) + throw new IllegalArgumentException(); + + while (categories.hasNext()) + { + Class cat = (Class) categories.next(); + if (cat == null) + throw new IllegalArgumentException(); + cats.add(cat); + } + + int numCats = cats.size(); + this.categories = (Class[]) cats.toArray(new Class[numCats]); + this.providers = new LinkedList[numCats]; + } + + + /** + * Finds service providers that are implementing the specified + * Service Provider Interface. + * + * <p><b>On-demand loading:</b> Loading and initializing service + * providers is delayed as much as possible. The rationale is that + * typical clients will iterate through the set of installed service + * providers until one is found that matches some criteria (like + * supported formats, or quality of service). In such scenarios, it + * might make sense to install only the frequently needed service + * providers on the local machine. More exotic providers can be put + * onto a server; the server will only be contacted when no suitable + * service could be found locally.</p> + * + * <p><b>Security considerations:</b> Any loaded service providers + * are loaded through the specified ClassLoader, or the system + * ClassLoader if <code>classLoader</code> is + * <code>null</code>. When <code>lookupProviders</code> is called, + * the current {@link java.security.AccessControlContext} gets + * recorded. This captured security context will determine the + * permissions when services get loaded via the <code>next()</code> + * method of the returned <code>Iterator</code>.</p> + * + * @param spi the service provider interface which must be + * implemented by any loaded service providers. + * + * @param loader the class loader that will be used to load the + * service providers, or <code>null</code> for the system class + * loader. For using the context class loader, see {@link + * #lookupProviders(Class)}. + * + * @return an iterator over instances of <code>spi</code>. + * + * @throws IllegalArgumentException if <code>spi</code> is + * <code>null</code>. + */ + public static <T> Iterator<T> lookupProviders(Class<T> spi, + ClassLoader loader) + { + return ServiceFactory.lookupProviders(spi, loader); + } + + + /** + * Finds service providers that are implementing the specified + * Service Provider Interface, using the context class loader + * for loading providers. + * + * @param spi the service provider interface which must be + * implemented by any loaded service providers. + * + * @return an iterator over instances of <code>spi</code>. + * + * @throws IllegalArgumentException if <code>spi</code> is + * <code>null</code>. + * + * @see #lookupProviders(Class, ClassLoader) + */ + public static <T> Iterator<T> lookupProviders(Class<T> spi) + { + return ServiceFactory.lookupProviders(spi); + } + + + /** + * Returns an iterator over all service categories. + * + * @return an unmodifiable {@link + * java.util.Iterator}<{@link java.lang.Class}>. + */ + public Iterator<Class<?>> getCategories() + { + return new Iterator() + { + int index = -1; + + public boolean hasNext() + { + return index < categories.length - 1; + } + + public Object next() + { + if (!hasNext()) + throw new NoSuchElementException(); + + return categories[++index]; + } + + public void remove() + { + throw new UnsupportedOperationException(); + } + }; + } + + + /** + * Registers a provider for a service category which is specified by + * the class-internal category ID. + * + * @param provider the service provider to be registered. + * + * @param cat the service category, which is identified by an index + * into the {@link #categories} array. + * + * @return <code>true</code> if <code>provider</code> is the first + * provider that gets registered for the specified service category; + * <code>false</code> if other providers have already been + * registered for the same servide category. + * + * @throws IllegalArgumentException if <code>provider</code> is + * <code>null</code>. + * + * @throws ClassCastException if <code>provider</code> does not + * implement the specified service provider interface. + */ + private synchronized boolean registerServiceProvider(Object provider, + int cat) + { + LinkedList provs; + boolean result; + Class category; + + if (provider == null) + throw new IllegalArgumentException(); + + category = categories[cat]; + if (!category.isInstance(provider)) + throw new ClassCastException(category.getName()); + + provs = providers[cat]; + if (provs == null) + { + result = true; + provs = providers[cat] = new LinkedList(); + } + else + result = false; + + provs.add(provider); + if (provider instanceof RegisterableService) + ((RegisterableService) provider).onRegistration(this, category); + + return result; + } + + + /** + * Registers a provider for the specified service category. + * + * <p>If <code>provider</code> implements the {@link + * RegisterableService} interface, its {@link + * RegisterableService#onRegistration onRegistration} method is + * invoked in order to inform the provider about the addition to + * this registry. + * + * @param provider the service provider to be registered. + * + * @param category the service category under which + * <code>provider</code> shall be registered. + * + * @return <code>true</code> if <code>provider</code> is the first + * provider that gets registered for the specified service category; + * <code>false</code> if other providers have already been + * registered for the same servide category. + * + * @throws IllegalArgumentException if <code>provider</code> is + * <code>null</code>, or if <code>category</code> is not among the + * categories passed to the {@linkplain #ServiceRegistry(Iterator) + * constructor} of this ServiceRegistry. + * + * @throws ClassCastException if <code>provider</code> does not + * implement <code>category</code>. + */ + public synchronized <T> boolean registerServiceProvider(T provider, + Class<T> category) + { + for (int i = 0; i < categories.length; i++) + if (categories[i] == category) + return registerServiceProvider(provider, i); + throw new IllegalArgumentException(); + } + + + /** + * Registers a provider under all service categories it + * implements. + * + * <p>If <code>provider</code> implements the {@link + * RegisterableService} interface, its {@link + * RegisterableService#onRegistration onRegistration} method is + * invoked in order to inform the provider about the addition to + * this registry. If <code>provider</code> implements several + * service categories, <code>onRegistration</code> gets called + * multiple times. + * + * @param provider the service provider to be registered. + * + * @throws IllegalArgumentException if <code>provider</code> is + * <code>null</code>, or if <code>provider</code> does not implement + * any of the service categories passed to the {@linkplain + * #ServiceRegistry(Iterator) constructor} of this ServiceRegistry. + */ + public synchronized void registerServiceProvider(Object provider) + { + boolean ok = false; + + if (provider == null) + throw new IllegalArgumentException(); + + for (int i = 0; i < categories.length; i++) + if (categories[i].isInstance(provider)) + { + ok = true; + registerServiceProvider(provider, i); + } + + if (!ok) + throw new IllegalArgumentException(); + } + + + /** + * Registers a number of providers under all service categories they + * implement. + * + * <p>If a provider implements the {@link RegisterableService} + * interface, its {@link RegisterableService#onRegistration + * onRegistration} method is invoked in order to inform the provider + * about the addition to this registry. If <code>provider</code> + * implements several service categories, + * <code>onRegistration</code> gets called multiple times. + * + * @throws IllegalArgumentException if <code>providers</code> is + * <code>null</code>, if any iterated provider is <code>null</code>, + * or if some iterated provider does not implement any of the + * service categories passed to the {@linkplain + * #ServiceRegistry(Iterator) constructor} of this + * <code>ServiceRegistry</code>. + */ + public synchronized void registerServiceProviders(Iterator<?> providers) + { + if (providers == null) + throw new IllegalArgumentException(); + + while (providers.hasNext()) + registerServiceProvider(providers.next()); + } + + + /** + * De-registers a provider for a service category which is specified + * by the class-internal category ID. + * + * @param provider the service provider to be registered. + * + * @param cat the service category, which is identified by an index + * into the {@link #categories} array. + * + * @return <code>true</code> if <code>provider</code> was previously + * registered for the specified service category; <code>false</code> + * if if the provider had not been registered. + * + * @throws IllegalArgumentException if <code>provider</code> is + * <code>null</code>. + * + * @throws ClassCastException if <code>provider</code> does not + * implement the specified service provider interface. + */ + private synchronized boolean deregisterServiceProvider(Object provider, + int cat) + { + LinkedList provs; + boolean result; + Class category; + + if (provider == null) + throw new IllegalArgumentException(); + + category = categories[cat]; + if (!category.isInstance(provider)) + throw new ClassCastException(category.getName()); + + provs = providers[cat]; + if (provs == null) + return false; + + result = provs.remove(provider); + if (provs.isEmpty()) + providers[cat] = null; + + if (result && (provider instanceof RegisterableService)) + ((RegisterableService) provider).onDeregistration(this, category); + + return result; + } + + + /** + * De-registers a provider for the specified service category. + * + * <p>If <code>provider</code> implements the {@link + * RegisterableService} interface, its {@link + * RegisterableService#onDeregistration onDeregistration} method is + * invoked in order to inform the provider about the removal from + * this registry. + * + * @param provider the service provider to be de-registered. + * + * @param category the service category from which + * <code>provider</code> shall be de-registered. + * + * @return <code>true</code> if <code>provider</code> was previously + * registered for the specified service category; <code>false</code> + * if if the provider had not been registered. + * + * @throws IllegalArgumentException if <code>provider</code> is + * <code>null</code>, or if <code>category</code> is not among the + * categories passed to the {@linkplain #ServiceRegistry(Iterator) + * constructor} of this ServiceRegistry. + * + * @throws ClassCastException if <code>provider</code> does not + * implement <code>category</code>. + */ + public synchronized <T> boolean deregisterServiceProvider(T provider, + Class<T> category) + { + for (int i = 0; i < categories.length; i++) + if (categories[i] == category) + return deregisterServiceProvider(provider, i); + throw new IllegalArgumentException(); + } + + + /** + * De-registers a provider from all service categories it + * implements. + * + * <p>If <code>provider</code> implements the {@link + * RegisterableService} interface, its {@link + * RegisterableService#onDeregistration onDeregistration} method is + * invoked in order to inform the provider about the removal from + * this registry. If <code>provider</code> implements several + * service categories, <code>onDeregistration</code> gets called + * multiple times.</p> + * + * @param provider the service provider to be de-registered. + * + * @throws IllegalArgumentException if <code>provider</code> is + * <code>null</code>, or if <code>provider</code> does not implement + * any of the service categories passed to the {@linkplain + * #ServiceRegistry(Iterator) constructor} of this + * <code>ServiceRegistry</code>. + */ + public synchronized void deregisterServiceProvider(Object provider) + { + boolean ok = false; + + if (provider == null) + throw new IllegalArgumentException(); + + for (int i = 0; i < categories.length; i++) + if (categories[i].isInstance(provider)) + { + ok = true; + deregisterServiceProvider(provider, i); + } + + if (!ok) + throw new IllegalArgumentException(); + } + + + /** + * De-registers all providers which have been registered for the + * specified service category. + * + * <p>If a provider implements the {@link RegisterableService} + * interface, its {@link RegisterableService#onDeregistration + * onDeregistration} method is invoked in order to inform the + * provider about the removal from this registry. If the provider + * implements several service categories, + * <code>onDeregistration</code> gets called multiple times. + * + * @param category the category whose registered providers will be + * de-registered. + * + * @throws IllegalArgumentException if <code>category</code> is not + * among the categories passed to the {@linkplain + * #ServiceRegistry(Iterator) constructor} of this + * <code>ServiceRegistry</code>. + */ + public synchronized void deregisterAll(Class<?> category) + { + boolean ok = false; + + for (int i = 0; i < categories.length; i++) + { + if (categories[i] != category) + continue; + + ok = true; + while (providers[i] != null) + deregisterServiceProvider(providers[i].get(0), i); + } + + if (!ok) + throw new IllegalArgumentException(); + } + + + /** + * De-registers all service providers. + * + * <p>If a provider implements the {@link RegisterableService} + * interface, its {@link RegisterableService#onDeregistration + * onDeregistration} method is invoked in order to inform the + * provider about the removal from this registry. If the provider + * implements several service categories, + * <code>onDeregistration</code> gets called multiple times. + */ + public synchronized void deregisterAll() + { + for (int i = 0; i < categories.length; i++) + while (providers[i] != null) + deregisterServiceProvider(providers[i].get(0), i); + } + + + /** + * Called by the Virtual Machine when it detects that this + * <code>ServiceRegistry</code> has become garbage. De-registers all + * service providers, which will cause those that implement {@link + * RegisterableService} to receive a {@link + * RegisterableService#onDeregistration onDeregistration} + * notification. + */ + public void finalize() + throws Throwable + { + super.finalize(); + deregisterAll(); + } + + + /** + * Determines whether a provider has been registered with this + * registry. + * + * @return <code>true</code> if <code>provider</code> has been + * registered under any service category; <code>false</code> if + * it is not registered. + * + * @throws IllegalArgumentException if <code>provider</code> is + * <code>null</code>. + */ + public synchronized boolean contains(Object provider) + { + if (provider == null) + throw new IllegalArgumentException(); + + // Note that contains is rather unlikely to be ever called, + // so it would be wasteful to keep a special data structure + // (such as a HashSet) for making it a fast operation. + for (int i = 0; i < providers.length; i++) + { + // If provider does not implement categories[i], + // it would not have been possible to register it there. + // In that case, it would be pointless to look there. + if (!categories[i].isInstance(provider)) + continue; + + // But if the list of registered providers contains provider, + // we have found it. + LinkedList p = providers[i]; + if (p != null && p.contains(provider)) + return true; + } + + return false; + } + + + /** + * Returns the index in {@link #categories} occupied by the + * specified service category. + * + * @throws IllegalArgumentException if <code>category</code> is not + * among the categories passed to the {@linkplain + * #ServiceRegistry(Iterator) constructor} of this ServiceRegistry. + */ + private int getCategoryID(Class category) + { + for (int i = 0; i < categories.length; i++) + if (categories[i] == category) + return i; + + throw new IllegalArgumentException(); + } + + + /** + * Retrieves all providers that have been registered for the + * specified service category. + * + * @param category the service category whose providers are + * to be retrieved. + * + * @param useOrdering <code>true</code> in order to retrieve the + * providers in an order imposed by the {@linkplain #setOrdering + * ordering constraints}; <code>false</code> in order to retrieve + * the providers in any order. + * + * @throws IllegalArgumentException if <code>category</code> is not + * among the categories passed to the {@linkplain + * #ServiceRegistry(Iterator) constructor} of this + * <code>ServiceRegistry</code>. + * + * @see #getServiceProviders(Class, Filter, boolean) + */ + public <T> Iterator<T> getServiceProviders(Class<T> category, + boolean useOrdering) + { + return getServiceProviders(category, null, useOrdering); + } + + + /** + * Retrieves all providers that have been registered for the + * specified service category and that satisfy the criteria + * of a custom filter. + * + * @param category the service category whose providers are + * to be retrieved. + * + * @param filter a custom filter, or <code>null</code> to + * retrieve all registered providers for the specified + * category. + * + * @param useOrdering <code>true</code> in order to retrieve the + * providers in an order imposed by the {@linkplain #setOrdering + * ordering constraints}; <code>false</code> in order to retrieve + * the providers in any order. + * + * @throws IllegalArgumentException if <code>category</code> is not + * among the categories passed to the {@linkplain + * #ServiceRegistry(Iterator) constructor} of this + * <code>ServiceRegistry</code>. + */ + public synchronized <T> Iterator<T> getServiceProviders(Class<T> category, + Filter filter, + boolean useOrdering) + { + int catid; + LinkedList provs; + ArrayList result; + + catid = getCategoryID(category); + provs = providers[catid]; + if (provs == null) + return Collections.EMPTY_LIST.iterator(); + + result = new ArrayList(provs.size()); + for (Iterator iter = provs.iterator(); iter.hasNext();) + { + Object provider = iter.next(); + if (filter == null || filter.filter(provider)) + result.add(provider); + } + + // If we are supposed to obey ordering constraints, and + // if any constraints have been imposed on the specified + // service category, sort the result. + if (useOrdering && constraints != null) + { + final Map cons = constraints[catid]; + if (cons != null) + Collections.sort(result, new Comparator() + { + public int compare(Object o1, Object o2) + { + Set s; + + if (o1 == o2) + return 0; + + s = (Set) cons.get(o1); + if (s != null && s.contains(o2)) + return -1; // o1 < o2 + + s = (Set) cons.get(o2); + if (s != null && s.contains(o1)) + return 1; // o1 > o2 + + return 0; // o1 == o2 + } + }); + } + + return result.iterator(); + } + + + /** + * Returns one of the service providers that is a subclass of the + * specified class. + * + * @param providerClass a class to search for. + */ + public synchronized <T> T getServiceProviderByClass(Class<T> providerClass) + { + if (providerClass == null) + throw new IllegalArgumentException(); + + // Note that the method getServiceProviderByClass is rather + // unlikely to be ever called, so it would be wasteful to keep a + // special data structure for making it a fast operation. + for (int cat = 0; cat < categories.length; cat++) + { + if (!categories[cat].isAssignableFrom(providerClass)) + continue; + + LinkedList provs = providers[cat]; + if (provs == null) + continue; + + for (Iterator iter = provs.iterator(); iter.hasNext();) + { + Object provider = iter.next(); + if (providerClass.isInstance(provider)) + return (T) provider; + } + } + + return null; + } + + + /** + * Adds an ordering constraint on service providers. + * + * @param category the service category to which an ordering + * constraint is to be added. + * + * @param firstProvider the provider which is supposed to come before + * <code>second</code>. + * + * @param secondProvider the provider which is supposed to come after + * <code>first</code>. + * + * @throws IllegalArgumentException if <code>first</code> and + * <code>second</code> are referring to the same object, or if one + * of them is <code>null</code>. + * + * @see #unsetOrdering + * @see #getServiceProviders(Class, Filter, boolean) + */ + public synchronized <T> boolean setOrdering(Class<T> category, + T firstProvider, + T secondProvider) + { + return addConstraint(getCategoryID(category), firstProvider, + secondProvider); + } + + + /** + * Removes an ordering constraint on service providers. + * + * @param category the service category from which an ordering + * constraint is to be removed. + * + * @param firstProvider the provider which is supposed to come before + * <code>second</code>. + * + * @param secondProvider the provider which is supposed to come after + * <code>first</code>. + * + * @throws IllegalArgumentException if <code>first</code> and + * <code>second</code> are referring to the same object, or if one + * of them is <code>null</code>. + * + * @see #setOrdering + */ + public synchronized <T> boolean unsetOrdering(Class<T> category, + T firstProvider, + T secondProvider) + { + return removeConstraint(getCategoryID(category), + firstProvider, secondProvider); + } + + + /** + * Adds an ordering constraint on service providers. + * + * @param catid the service category ID, which is the + * category’s index into the {@link #categories} array. + * + * @param first the provider which is supposed to come before + * <code>second</code>. + * + * @param second the provider which is supposed to come after + * <code>first</code>. + * + * @throws IllegalArgumentException if <code>first</code> and + * <code>second</code> are referring to the same object, or if one + * of them is <code>null</code>. + */ + private boolean addConstraint(int catid, Object first, Object second) + { + Set s; + IdentityHashMap cons; + + // Also checks argument validity. + removeConstraint(catid, second, first); + + if (constraints == null) + constraints = new IdentityHashMap[categories.length]; + cons = constraints[catid]; + if (cons == null) + cons = constraints[catid] = new IdentityHashMap(); + + s = (Set) cons.get(first); + if (s == null) + cons.put(first, s = new HashSet()); + return s.add(second); + } + + + /** + * Removes an ordering constraint on service providers. + * + * @param catid the service category ID, which is the + * category’s index into the {@link #categories} array. + * + * @param first the provider which is supposed to come before + * <code>second</code>. + * + * @param second the provider which is supposed to come after + * <code>first</code>. + * + * @throws IllegalArgumentException if <code>first</code> and + * <code>second</code> are referring to the same object, or if one + * of them is <code>null</code>. + */ + private boolean removeConstraint(int catid, Object first, Object second) + { + Collection s; + IdentityHashMap cons; + + if (first == null || second == null || first == second) + throw new IllegalArgumentException(); + + if (constraints == null) + return false; + + cons = constraints[catid]; + if (cons == null) + return false; + + s = (Collection) cons.get(first); + if (s == null) + return false; + + if (!s.remove(second)) + return false; + + // If we removed the last constraint for a service category, + // we can get free some memory. + if (cons.isEmpty()) + { + constraints[catid] = null; + boolean anyConstraints = false; + for (int i = 0; i < constraints.length; i++) + { + if (constraints[i] != null) + { + anyConstraints = true; + break; + } + } + if (!anyConstraints) + constraints = null; + } + + return true; + } + + + /** + * A filter for selecting service providers that match custom + * criteria. + * + * @see ServiceRegistry#getServiceProviders(Class, Filter, + * boolean) + * + * @since 1.4 + * + * @author Michael Koch (konqueror@gmx.de) + * @author Sascha Brawer (brawer@dandelis.ch) + */ + public static interface Filter + { + /** + * Checks whether the specified service provider matches the + * constraints of this Filter. + * + * @param provider the service provider in question. + * + * @return <code>true</code> if <code>provider</code> matches the + * criteria; <code>false</code> if it does not match. + */ + boolean filter(Object provider); + } +} diff --git a/libjava/classpath/javax/imageio/spi/package.html b/libjava/classpath/javax/imageio/spi/package.html new file mode 100644 index 000000000..69fe33f60 --- /dev/null +++ b/libjava/classpath/javax/imageio/spi/package.html @@ -0,0 +1,46 @@ +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> +<!-- package.html - describes classes in javax.imageio.spi package. + Copyright (C) 2004 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. --> + +<html> +<head><title>GNU Classpath - javax.imageio.spi</title></head> + +<body> +<p></p> + +</body> +</html> |