Source Code Cross Referenced for OperationRegistry.java in  » 6.0-JDK-Modules » Java-Advanced-Imaging » javax » media » jai » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » Java Advanced Imaging » javax.media.jai 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * $RCSfile: OperationRegistry.java,v $
0003:         *
0004:         * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * Use is subject to license terms.
0007:         *
0008:         * $Revision: 1.1 $
0009:         * $Date: 2005/02/11 04:57:13 $
0010:         * $State: Exp $
0011:         */
0012:        package javax.media.jai;
0013:
0014:        import com.sun.media.jai.util.PropertyUtil;
0015:        import com.sun.media.jai.util.Service;
0016:        import java.awt.RenderingHints;
0017:        import java.awt.image.renderable.ContextualRenderedImageFactory;
0018:        import java.awt.image.renderable.ParameterBlock;
0019:        import java.awt.image.renderable.RenderedImageFactory;
0020:        import java.io.BufferedWriter;
0021:        import java.io.ByteArrayInputStream;
0022:        import java.io.ByteArrayOutputStream;
0023:        import java.io.Externalizable;
0024:        import java.io.FileInputStream;
0025:        import java.io.FileNotFoundException;
0026:        import java.io.IOException;
0027:        import java.io.InputStream;
0028:        import java.io.ObjectInput;
0029:        import java.io.ObjectOutput;
0030:        import java.io.OutputStream;
0031:        import java.io.StringWriter;
0032:        import java.net.URL;
0033:        import java.text.MessageFormat;
0034:        import java.util.ArrayList;
0035:        import java.util.Enumeration;
0036:        import java.util.HashSet;
0037:        import java.util.Hashtable;
0038:        import java.util.Iterator;
0039:        import java.util.List;
0040:        import java.util.Locale;
0041:        import java.util.Vector;
0042:        import javax.media.jai.registry.CIFRegistry;
0043:        import javax.media.jai.registry.CRIFRegistry;
0044:        import javax.media.jai.registry.RIFRegistry;
0045:        import javax.media.jai.registry.CollectionRegistryMode;
0046:        import javax.media.jai.registry.RenderableRegistryMode;
0047:        import javax.media.jai.registry.RenderedRegistryMode;
0048:        import javax.media.jai.util.CaselessStringKey;
0049:        import javax.media.jai.util.ImagingException;
0050:        import javax.media.jai.util.ImagingListener;
0051:        import com.sun.media.jai.util.ImageUtil;
0052:
0053:        /**
0054:         * A class responsible for maintaining a registry of various types of
0055:         * factory objects and preferences among them. The operation registry
0056:         * hierarchy looks as follows
0057:         *
0058:         * <pre>
0059:         *
0060:         *                                                      |-object1-
0061:         *                                           |-product1-|-object2-
0062:         *                             |-descriptor1-|          |-object3-
0063:         *                             |             |
0064:         *                             |             |          |-object1-
0065:         *                             |             |-product2-|-object2-
0066:         *                     |-mode1-|                        |-object3-
0067:         *                     |       |
0068:         * |-OperationRegistry-|       |                        |-object1-
0069:         *                     |       |             |-product1-|-object2-
0070:         *                     |       |-descriptor2-|          |-object3-
0071:         *                     |                     |
0072:         *                     |                     |          |-object1-
0073:         *                     |                     |-product2-|-object2-
0074:         *                     |                                |-object3-
0075:         *                     |
0076:         *                     |-mode2-|-descriptor1-|-object1--
0077:         *                             |
0078:         *                             |-descriptor2-|-object1--
0079:         * </pre>
0080:         *
0081:         * <p> The <code>OperationRegistry</code> class maps a descriptor name
0082:         * (for example, an image operation name) into the particular kind of
0083:         * factory object requested, capable of implementing the functionality
0084:         * described by the descriptor. The mapping is constructed in several
0085:         * stages:
0086:         *
0087:         * <p> At the highest level all objects are registered against some mode.
0088:         * A mode is specified by a <code>String</code> which must be one
0089:         * of those returned by <code>RegistryMode.getModeNames()</code>.
0090:         * Examples of known registry modes include "rendered", "renderable",
0091:         * "collection", "renderableCollection", "tileEncoder", "tileDecoder",
0092:         * "remoteRendered", "remoteRenderable", etc.
0093:         *
0094:         * <p> Each registry mode is associated with a <code>
0095:         * RegistryElementDescriptor</code> which describes some functionality
0096:         * to be implemented by factory objects associated with this
0097:         * descriptor. For example, the "rendered" registry mode is associated
0098:         * with <code>OperationDescriptor.class</code> and "tileEncoder"
0099:         * is associated with <code>TileCodecDescriptor.class</code>.
0100:         * Different registry modes can share the same <code>
0101:         * RegistryElementDescriptor</code>. For example "rendered", "renderable"
0102:         * (and other image operation registry modes) are all associated with
0103:         * <code>OperationDescriptor.class</code>.
0104:         *
0105:         * <p> If a registry mode supports preferences (for example "rendered",
0106:         * "tileEncoder" etc.), then the hierarchy of objects registered under
0107:         * that mode looks like that of "mode1" above. Descriptors are first
0108:         * registered against all modes that the specific instance supports. Each
0109:         * factory object that implements the functionality specified by that
0110:         * descriptor is registered against some product (name) under that
0111:         * descriptor. Preferences can be set among products under a given
0112:         * descriptor or among objects under a specific product/descriptor.
0113:         *
0114:         * <p> The ordering of such factory objects is determined by the order
0115:         * of the products attached to an <code>OperationDescriptor</code>,
0116:         * and by the order of the factory objects within each product. The
0117:         * orders are established by setting pairwise preferences, resulting in
0118:         * a partial order which is then sorted topologically. The results of
0119:         * creating a cycle are undefined.
0120:         *
0121:         * <p> The ordering of factory objects within a product is intended to
0122:         * allow vendors to create complex "fallback" chains. An example would
0123:         * be installing a <code>RenderedImageFactory</code> that implements
0124:         * separable convolution ahead of a <code>RenderedImageFactory</code>
0125:         * that implements a more general algorithm.
0126:         *
0127:         * <p> If a registry mode does not support preferences (for example,
0128:         * "renderable", "remoteRenderable" etc.) then the hierarchy of objects
0129:         * registered under that mode looks like that of "mode2" above. Only a
0130:         * single factory object belonging to this mode can be associated with a
0131:         * given descriptor. If multiple objects are registered under the same
0132:         * descriptor, the last one registered is retained.
0133:         *
0134:         * <p> The <code>OperationRegistry</code> has several methods to manage this
0135:         * hierarchy, which accept a <code>modeName</code> and work with <code>
0136:         * Object</code>s. The preferred manner of usage is through the type-safe
0137:         * wrapper class which are specific to each mode (for example <code>
0138:         * RIFRegistry</code>, <code>CRIFRegistry</code> etc.)
0139:         *
0140:         * <p> Vendors are encouraged to use unique product names (by means
0141:         * of the Java programming language convention of reversed Internet
0142:         * addresses) in order to maximize the likelihood of clean installation.
0143:         * See <i>The Java Programming Language</i>, &sect;10.1 for a discussion
0144:         * of this convention in the context of package naming.
0145:         *
0146:         * <p> Users will, for the most part, only wish to set ordering
0147:         * preferences on the product level, since the factory object level
0148:         * orderings will be complex. However, it is possible for a knowledgable
0149:         * user to insert a specific factory object into an existing product for
0150:         * tuning purposes.
0151:         *
0152:         * <p> The <code>OperationRegistry</code> also has the responsibility
0153:         * of associating a set of <code>PropertyGenerators</code>
0154:         * with each descriptor. This set will be coalesced
0155:         * into a <code>PropertySource</code> suitable for
0156:         * use by the getPropertySource() method. If several
0157:         * <code>PropertyGenerator</code>s associated with a particular
0158:         * descriptor generate the same property, only the last one to be
0159:         * registered will have any effect.
0160:         *
0161:         * <p> The registry handles all names (except class names) in a
0162:         * case-insensitive but retentive manner.
0163:         *
0164:         *
0165:         * <p><strong>Initialization and automatic loading of registry objects. </strong>
0166:         *
0167:         * <p> The user has two options for automatic loading of registry
0168:         * objects.
0169:         * <ul>
0170:         * <li> For most normal situations the user can create a
0171:         *      "<code>registryFile.jai</code>" with entries for operators and preferences
0172:         *      specific to their packages. This registry file must be put it in
0173:         *      the META-INF directory of the jarfile or classpath.
0174:         *
0175:         * <li> For situations where more control over the operation registry is
0176:         *      needed, (for example remove an operator registered by JAI etc.) the
0177:         *      user can implement a concrete sub-class of the <code>
0178:         *	OperationRegistrySpi</code> interface
0179:         *      and register it as service provider (see <code>
0180:         *      OperationRegistrySpi</code> for more details). The <code>updateRegistry
0181:         *      </code> method of such registered service providers will be called
0182:         *      with the default <code>OperationRegistry</code> of <code>JAI</code>
0183:         *      once it has been initialized.
0184:         * </ul>
0185:         *
0186:         * <p> The initialization of the <code>OperationRegistry</code>
0187:         * of the default instance of <code>JAI</code> happens as follows
0188:         * <ol>
0189:         * <li> Load the JAI distributed registry file
0190:         *      "<code>META-INF/javax.media.jai.registryFile.jai</code>" (from jai_core.jar)
0191:         *
0192:         * <li> Find and load all "<code>META-INF/registryFile.jai</code>" files found
0193:         *      in the classpath in some arbitrary order.
0194:         *
0195:         * <li> Look for registered service providers of <code>OperationRegistrySpi</code>
0196:         *	listed in all "<code>META-INF/services/javax.media.jai.OperationRegistrySpi</code>"
0197:         *	files found in the classpath and call their <code>updateRegistry</code>
0198:         *      method passing in the default OperationRegistry. The order of these
0199:         *      calls to <code>updateRegistry</code> is arbitrary.
0200:         * </ol>
0201:         *
0202:         * Note that the user should not make any assumption about the order
0203:         * of loading WITHIN step 2 or 3. If there is a need for the
0204:         * <code>updateRegistry</code> method to be called right after the associated
0205:         * registryFile.jai is read in, the following could be done.
0206:         *
0207:         * <p> The user could give the registry file a package qualified name
0208:         * for e.g xxx.yyy.registryFile.jai and put this in the META-INF
0209:         * directory of the jar file. Then in the concrete class that implements
0210:         * <code>OperationRegistrySpi</code>
0211:         *
0212:         * <pre>
0213:         *  void updateRegistry(OperationRegistry or) {
0214:         *      String registryFile = "META-INF/xxx.yyy.registryFile.jai";
0215:         *      InputStream is = ClassLoader.getResourceAsStream(registryFile);
0216:         *
0217:         *      or.updateFromStream(is);
0218:         *
0219:         *      // Make other changes to "or" ...
0220:         *  }
0221:         * </pre>
0222:         *
0223:         * For information on the format of the registry file, see the
0224:         * <a href="{@docRoot}/serialized-form.html#javax.media.jai.OperationRegistry">
0225:         * serialized form</a> of the <code>OperationRegistry</code>.
0226:         *
0227:         * @see OperationRegistrySpi
0228:         * @see RegistryMode
0229:         * @see RegistryElementDescriptor
0230:         */
0231:        public class OperationRegistry implements  Externalizable {
0232:
0233:            /** The JAI packaged registry file */
0234:            static String JAI_REGISTRY_FILE = "META-INF/javax.media.jai.registryFile.jai";
0235:
0236:            /** The user defined registry files that are automatically loaded */
0237:            static String USR_REGISTRY_FILE = "META-INF/registryFile.jai";
0238:
0239:            /**
0240:             * A <code>Hashtable</code> of <code>DescritptorCache</code>s
0241:             * for each registry mode.
0242:             */
0243:            private Hashtable descriptors;
0244:
0245:            /**
0246:             * A <code>Hashtable</code> of <code>FactoryCache</code>s
0247:             * for each registry mode.
0248:             */
0249:            private Hashtable factories;
0250:
0251:            /**
0252:             * Get the <code>FactoryCache</code> associated with a specified
0253:             * mode. If it does not exist but the mode is a valid registry mode
0254:             * then silently create one.
0255:             */
0256:            private FactoryCache getFactoryCache(String modeName) {
0257:
0258:                CaselessStringKey key = new CaselessStringKey(modeName);
0259:
0260:                FactoryCache fc = (FactoryCache) factories.get(key);
0261:
0262:                if (fc == null) {
0263:
0264:                    if (RegistryMode.getMode(modeName) != null) {
0265:                        factories.put(key, fc = new FactoryCache(modeName));
0266:
0267:                    } else {
0268:                        throw new IllegalArgumentException(JaiI18N
0269:                                .formatMsg("OperationRegistry0",
0270:                                        new Object[] { modeName }));
0271:                    }
0272:                }
0273:
0274:                return fc;
0275:            }
0276:
0277:            /**
0278:             * Get the <code>DescriptorCache</code> associated with a specified
0279:             * mode. If it does not exist but the mode is a valid registry mode
0280:             * then silently create one.
0281:             */
0282:            private DescriptorCache getDescriptorCache(String modeName) {
0283:
0284:                CaselessStringKey key = new CaselessStringKey(modeName);
0285:
0286:                DescriptorCache dc = (DescriptorCache) descriptors.get(key);
0287:
0288:                if (dc == null) {
0289:
0290:                    if (RegistryMode.getMode(modeName) != null) {
0291:                        descriptors
0292:                                .put(key, dc = new DescriptorCache(modeName));
0293:
0294:                    } else {
0295:                        throw new IllegalArgumentException(JaiI18N
0296:                                .formatMsg("OperationRegistry0",
0297:                                        new Object[] { modeName }));
0298:                    }
0299:                }
0300:
0301:                return dc;
0302:            }
0303:
0304:            /**
0305:             * Initialize all the internal OperationRegistry fields.
0306:             *
0307:             * Note that this is not synchronized. It is the caller's
0308:             * reponsiblity to make sure that thread safety is maintained.
0309:             */
0310:            private void initialize() {
0311:
0312:                // Create a Hashtable to hold a DescriptorCache for each
0313:                // known registry mode.
0314:                descriptors = new Hashtable();
0315:
0316:                // Create a Hashtable to hold a FactoryCache for each
0317:                // known registry mode.
0318:                factories = new Hashtable();
0319:            }
0320:
0321:            /**
0322:             * Default Constructor. The <code>OperationRegistry</code> created is
0323:             * <u>not</u> thread-safe. Note that none of the automatic loading
0324:             * of registry files or services happens here.
0325:             *
0326:             * @see #getThreadSafeOperationRegistry
0327:             */
0328:            public OperationRegistry() {
0329:                initialize();
0330:            }
0331:
0332:            /**
0333:             * Creates and returns a new thread-safe version of the
0334:             * <code>OperationRegistry</code> which uses reader-writer locks to
0335:             * wrap every method with a read or a write lock as appropriate.
0336:             * Note that none of the automatic loading of registry files or
0337:             * services is done on this <code>OperationRegistry</code>.
0338:             *
0339:             * @since JAI 1.1
0340:             */
0341:            public static OperationRegistry getThreadSafeOperationRegistry() {
0342:                return new ThreadSafeOperationRegistry();
0343:            }
0344:
0345:            /**
0346:             * Creates a new thread-safe <code>OperationRegistry</code>. It
0347:             * is initialized by first reading in the system distributed
0348:             * registry file (<code>JAI_REGISTRY_FILE</code>), then the user
0349:             * installed registry files (<code>USR_REGISTRY_FILE</code>) and
0350:             * then by calling the <code>updateRegistry()</code> method of all
0351:             * registered service providers.
0352:             *
0353:             * @return a properly initialized thread-safe
0354:             *		<code>OperationRegistry</code>
0355:             */
0356:            static OperationRegistry initializeRegistry() {
0357:                try {
0358:                    InputStream url = PropertyUtil
0359:                            .getFileFromClasspath(JAI_REGISTRY_FILE);
0360:
0361:                    if (url == null) {
0362:                        throw new RuntimeException(JaiI18N
0363:                                .getString("OperationRegistry1"));
0364:                    }
0365:
0366:                    OperationRegistry registry = new ThreadSafeOperationRegistry();
0367:
0368:                    if (url != null)
0369:                        RegistryFileParser.loadOperationRegistry(registry,
0370:                                null, url);
0371:
0372:                    registry.registerServices(null);
0373:                    return registry;
0374:
0375:                } catch (IOException ioe) {
0376:                    ImagingListener listener = JAI.getDefaultInstance()
0377:                            .getImagingListener();
0378:                    String message = JaiI18N.getString("OperationRegistry2");
0379:                    listener.errorOccurred(message, new ImagingException(
0380:                            message, ioe), OperationRegistry.class, false);
0381:                    return null;
0382:
0383:                    //	    ioe.printStackTrace();
0384:                    //	    throw new RuntimeException(
0385:                    //			JaiI18N.getString("OperationRegistry2"));
0386:                }
0387:            }
0388:
0389:            /**
0390:             * Returns a String representation of the registry.
0391:             *
0392:             * @return  the string representation of this <code>OperationRegistry</code>.
0393:             */
0394:            public String toString() {
0395:
0396:                StringWriter sw = new StringWriter();
0397:
0398:                try {
0399:                    RegistryFileParser.writeOperationRegistry(this ,
0400:                            new BufferedWriter(sw));
0401:                    return sw.getBuffer().toString();
0402:
0403:                } catch (Exception e) {
0404:                    return "\n[ERROR!] " + e.getMessage();
0405:                }
0406:            }
0407:
0408:            /**
0409:             * Writes out the contents of the <code>OperationRegistry</code> to
0410:             * a stream as specified in the <code>writeExternal</code> method.
0411:             * For more information see the
0412:             * <a href="{@docRoot}/serialized-form.html#javax.media.jai.OperationRegistry"> serialized form</a>.
0413:             *
0414:             * @param out  The OutputStream to which the <code>OperationRegistry</code>
0415:             *             state is written.
0416:             *
0417:             * @throws IllegalArgumentException if out is null.
0418:             *
0419:             * @see #writeExternal
0420:             */
0421:            public void writeToStream(OutputStream out) throws IOException {
0422:                if (out == null)
0423:                    throw new IllegalArgumentException(JaiI18N
0424:                            .getString("Generic0"));
0425:
0426:                RegistryFileParser.writeOperationRegistry(this , out);
0427:            }
0428:
0429:            /**
0430:             * Initializes the <code>OperationRegistry</code> from an
0431:             * <code>InputStream</code>. All non-IO exceptions encountered while
0432:             * parsing the registry files are caught and their error messages are
0433:             * redirected to <code>System.err</code>. If <code>System.err</code>
0434:             * is null the error messages will never be seen.
0435:             *
0436:             * <p> The <code>InputStream</code> passed in will not be closed by
0437:             * this method, the caller should close the <code>InputStream</code>
0438:             * when it is no longer needed.
0439:             *
0440:             * <p>The format of the data from the <code>InputStream</code> is
0441:             * expected to be the same as that of the <code>writeExternal</code>
0442:             * method as specified in the
0443:             * <a href="{@docRoot}/serialized-form.html#javax.media.jai.OperationRegistry"> serialized form</a>.
0444:             *
0445:             * @param in   The <code>InputStream</code> from which to read the data.
0446:             *
0447:             * @throws IllegalArgumentException if in is null.
0448:             *
0449:             * @see #writeExternal
0450:             */
0451:            public void initializeFromStream(InputStream in) throws IOException {
0452:
0453:                if (in == null)
0454:                    throw new IllegalArgumentException(JaiI18N
0455:                            .getString("Generic0"));
0456:
0457:                initialize();
0458:                updateFromStream(in);
0459:            }
0460:
0461:            /**
0462:             * Updates the current <code>OperationRegistry</code> with the
0463:             * operations specified by the given <code>InputStream</code>.
0464:             * All non-IO exceptions encountered while parsing the registry
0465:             * files are caught and their error messages are redirected to
0466:             * <code>System.err</code>. If <code>System.err</code> is null the
0467:             * error messages will never be seen.
0468:             *
0469:             * <p> The <code>InputStream</code> passed in will not be closed by
0470:             * this method, the caller should close the <code>InputStream</code>
0471:             * when it is no longer needed.
0472:             *
0473:             * <p>The format of the data from the <code>InputStream</code> is
0474:             * expected to be the same as that of the <code>writeExternal</code>
0475:             * method as specified in the
0476:             * <a href="{@docRoot}/serialized-form.html#javax.media.jai.OperationRegistry"> serialized form</a>.
0477:             *
0478:             * @param in   The <code>InputStream</code> from which to read the data.
0479:             *
0480:             * @throws IllegalArgumentException if in is null.
0481:             *
0482:             * @see #writeExternal
0483:             *
0484:             * @since JAI 1.1
0485:             */
0486:            public void updateFromStream(InputStream in) throws IOException {
0487:
0488:                if (in == null)
0489:                    throw new IllegalArgumentException(JaiI18N
0490:                            .getString("Generic0"));
0491:
0492:                RegistryFileParser.loadOperationRegistry(this , null, in);
0493:            }
0494:
0495:            /**
0496:             * Restores the contents of the registry from an ObjectInput which
0497:             * was previously written using the <code>writeExternal</code>
0498:             * method.
0499:             *
0500:             * <p>All non-IO exceptions encountered while parsing the registry
0501:             * files are caught and their error messages are redirected to
0502:             * <code>System.err</code>. If <code>System.err</code> is null the
0503:             * error messages will never be seen.
0504:             *
0505:             * @param in   An ObjectInput from which to read the data.
0506:             *
0507:             * @serialData The format of the data from the ObjectInput
0508:             * is expected to be the same as that written out by the
0509:             * <code>writeExternal</code> method. For more information see
0510:             * <a href="{@docRoot}/serialized-form.html#javax.media.jai.OperationRegistry"> serialized form</a>.
0511:             * The current implementation is backward compatible with the old
0512:             * JAI 1.0.2 registry file streams.
0513:             *
0514:             * @throws IllegalArgumentException if in is null.
0515:             *
0516:             * @see #writeExternal
0517:             */
0518:            public void readExternal(ObjectInput in) throws IOException,
0519:                    ClassNotFoundException {
0520:
0521:                if (in == null)
0522:                    throw new IllegalArgumentException(JaiI18N
0523:                            .getString("Generic0"));
0524:
0525:                byte barray[] = (byte[]) in.readObject();
0526:                InputStream s = new ByteArrayInputStream(barray);
0527:                initializeFromStream(s);
0528:            }
0529:
0530:            /**
0531:             * Saves the contents of the registry as described in the
0532:             * <a href="{@docRoot}/serialized-form.html#javax.media.jai.OperationRegistry"> serialized form</a>.
0533:             *
0534:             * @param out   An ObjectOutput to which to write the data.
0535:             *
0536:             * @throws IllegalArgumentException if out is null.
0537:             *
0538:             * @serialData The format of the data written to the stream is as
0539:             * follows. Each line in the stream can be in one of the formats
0540:             * described below. Space or tab characters seperate keywords in
0541:             * each line. The comment character is <tt>'#'</tt> (<tt>0x23</tt>);
0542:             * on each line all characters following the first comment character
0543:             * are ignored. The stream must be encoded in UTF-8.
0544:             *
0545:             * <p><ol>
0546:             *
0547:             * <li> To register descriptors :<p>
0548:             *
0549:             * <b>descriptor</b> <i>{descriptor-class-name}</i><p>
0550:             * <b>odesc</b>	 <i>{descriptor-class-name}  {descriptor-name}</i><p>
0551:             *
0552:             * <p>The second version above is deprecated and is retained for backward
0553:             * compatibility with JAI 1.0.2. Descriptors are always registered
0554:             * against <i>{descriptor-class}.getName()</i>. The <i>{descriptor-name}</i> in the
0555:             * second version is always ignored.<p>
0556:             *
0557:             * <li> To register factory objects under a product against a specific mode :<p>
0558:             *
0559:             * <b>{registry-mode-name}</b>  <i>{factory-class-name}	{product-name}	{descriptor-name}   {local-name}</i><p>
0560:             * <b>{registry-mode-name}</b>  <i>{factory-class-name}	{descriptor-name}</i><p>
0561:             *
0562:             * <p>The first version above is used to register factory objects against
0563:             * modes that support preferences. The second version is used for those
0564:             * that do not support preferences. <i>{local-name},</i> is an arbitrary name that
0565:             * is unique for a given mode. This is (only) used later on in this file
0566:             * to set preferences between factory objects. See class comments
0567:             * for {@link OperationRegistry} for a discussion on product names.<p>
0568:             *
0569:             * <li> To set preferences between products for a descriptor under a
0570:             * specific mode :<p>
0571:             *
0572:             * <b>prefProduct	{registry-mode-name}</b>	<i>{descriptor-name}   {preferred-product-name} {other-product-name}</i><p>
0573:             * <b>pref	product</b>	<i>{descriptor-name}   {preferred-product-name} {other-product-name}</i><p>
0574:             *
0575:             * <p>The second version above is deprecated and is retained for backward
0576:             * compatibility with JAI 1.0.2. This version is assumed to set
0577:             * product preferences for the <i>"rendered"</i> mode.<p>
0578:             *
0579:             * <li> To set preferences between factory objects for descriptor under a
0580:             * a specific product and registry mode :<p>
0581:             *
0582:             * <b>pref</b>  <i>{registry-mode-name}  {descriptor-name}	{product-name}	{preferred-factory-local-name}	{other-factory-local-name}</i><p>
0583:             * </ol>
0584:             *
0585:             * <p>For example, the stream contents for an "addconst" image operation
0586:             * descriptor might look like this :
0587:             *
0588:             * <pre>
0589:             *    descriptor  javax.media.jai.operator.AddConstDescriptor
0590:             *
0591:             *    rendered    com.sun.media.jai.opimage.AddConstCRIF   com.sun.media.jai   addconst   sunaddconstrif
0592:             *    rendered    com.sun.media.jai.mlib.MlibAddConstRIF   com.sun.media.jai   addconst   mlibaddconstrif
0593:             *
0594:             *    renderable  com.sun.media.jai.opimage.AddConstCRIF   addconst
0595:             *
0596:             *    pref        rendered   addconst   com.sun.media.jai   mlibaddconstrif   sunaddconstrif
0597:             * </pre>
0598:             *
0599:             * The above does the following :
0600:             * <ul>
0601:             * <li> register a descriptor for the "addconst" operator. </li>
0602:             * <li> registers two <i>rendered</i> image factories. </li>
0603:             * <li> register one <i>renderable</i> image factory. </li>
0604:             * <li> prefer the MlibAddConstRIF factory over the AddConstCRIF
0605:             * factory for the <i>rendered</i> mode.</li>
0606:             *
0607:             * <p><strong>Note that JAI 1.0.2 will not be able to read the
0608:             * new version of the registry file streams</strong>.
0609:             */
0610:            public void writeExternal(ObjectOutput out) throws IOException {
0611:
0612:                if (out == null)
0613:                    throw new IllegalArgumentException(JaiI18N
0614:                            .getString("Generic0"));
0615:
0616:                ByteArrayOutputStream bstream = new ByteArrayOutputStream();
0617:                writeToStream(bstream);
0618:                out.writeObject(bstream.toByteArray());
0619:            }
0620:
0621:            /********************** NEW JAI 1.1 methods *************************/
0622:
0623:            /**
0624:             * Remove a registry mode (including pre-defined JAI modes) from
0625:             * the OperationRegistry. When a mode is removed, all associated descriptors
0626:             * are also removed unless associated with another mode. Note
0627:             * that this does <u>not</u> unregister or remove this mode from
0628:             * <code>RegistryMode</code>
0629:             *
0630:             * Also note that a registry mode need not be explicitly added to
0631:             * the <code>OperationRegistry</code>. All modes registered under
0632:             * <code>RegistryMode</code> are automatically recognized by the
0633:             * <code>OperationRegistry</code>.
0634:             *
0635:             * @throws IllegalArgumentException if modeName is <code>null</code>
0636:             *          or if the modeName is not one of the modes returned
0637:             *          <code>RegistryMode.getModes()</code>
0638:             *
0639:             * @since JAI 1.1
0640:             */
0641:            public void removeRegistryMode(String modeName) {
0642:
0643:                if (getDescriptorCache(modeName) != null)
0644:                    descriptors.remove(new CaselessStringKey(modeName));
0645:
0646:                if (getFactoryCache(modeName) != null)
0647:                    factories.remove(new CaselessStringKey(modeName));
0648:            }
0649:
0650:            /**
0651:             * Get's the list of known registry modes known to the
0652:             * <code>OperationRegistry</code>. This might not be all
0653:             * modes listed in <code>RegistryMode.getModeNames()</code>.
0654:             *
0655:             * @since JAI 1.1
0656:             */
0657:            public String[] getRegistryModes() {
0658:
0659:                Enumeration e = descriptors.keys();
0660:                int size = descriptors.size();
0661:                String names[] = new String[size];
0662:
0663:                for (int i = 0; i < size; i++) {
0664:                    CaselessStringKey key = (CaselessStringKey) e.nextElement();
0665:                    names[i] = key.getName();
0666:                }
0667:
0668:                return names;
0669:            }
0670:
0671:            //////////////////
0672:            //
0673:            // Set of methods to register/unregister descriptors
0674:            // with the operation registry.
0675:
0676:            /**
0677:             * Register a descriptor against all the registry modes it
0678:             * supports. The "descriptor" must be an instance of the
0679:             * RegistryMode.getDescriptorClass() The "descriptor" is keyed on
0680:             * descriptor.getName(). Only one descriptor can be registered
0681:             * against a descriptor name for a given mode.
0682:             *
0683:             * @param descriptor an instance of a concrete sub-class of <code>
0684:             *     RegistryElementDescriptor</code>
0685:             *
0686:             * @throws IllegalArgumentException is descriptor is <code>null</code>
0687:             * @throws IllegalArgumentException if any of the modes returned
0688:             *     by <code>descriptor.getSupportedModes()</code> is not one
0689:             *     of those returned by <code>RegistryMode.getModes()</code>
0690:             * @throws IllegalArgumentException if another descriptor with the
0691:             *	    same name has already been registered against any of the
0692:             *	    modes supported by this descriptor.
0693:             *
0694:             * @since JAI 1.1
0695:             */
0696:            public void registerDescriptor(RegistryElementDescriptor descriptor) {
0697:                if (descriptor == null)
0698:                    throw new IllegalArgumentException(JaiI18N
0699:                            .getString("Generic0"));
0700:
0701:                String[] supportedModes = descriptor.getSupportedModes();
0702:
0703:                String descriptorName = descriptor.getName();
0704:
0705:                // First make sure that all supported modes are legal registry
0706:                // modes.
0707:                for (int i = 0; i < supportedModes.length; i++) {
0708:                    if (RegistryMode.getMode(supportedModes[i]) == null)
0709:                        throw new IllegalArgumentException(JaiI18N.formatMsg(
0710:                                "OperationRegistry3", new Object[] {
0711:                                        descriptorName, supportedModes[i] }));
0712:                }
0713:
0714:                // Now register the descriptor against each supported mode.
0715:                for (int i = 0; i < supportedModes.length; i++) {
0716:
0717:                    DescriptorCache dc = getDescriptorCache(supportedModes[i]);
0718:
0719:                    dc.addDescriptor(descriptor);
0720:                }
0721:            }
0722:
0723:            /**
0724:             * Unregister a descriptor against all its supported modes from the
0725:             * operation registry.
0726:             *
0727:             * @param descriptor an instance of a concrete sub-class of <code>
0728:             *     RegistryElementDescriptor</code>
0729:             *
0730:             * @throws IllegalArgumentException is descriptor is <code>null</code>
0731:             * @throws IllegalArgumentException if any of the modes returned
0732:             *     by <code>descriptor.getSupportedModes()</code> is not one
0733:             *     of those returned by <code>RegistryMode.getModes()</code>
0734:             * @throws IllegalArgumentException if any of the
0735:             *     <code>PropertyGenerator</code>s associated with the
0736:             *     <code>RegistryElementDescriptor</code> to be unregistered is null.
0737:             *
0738:             * @since JAI 1.1
0739:             */
0740:            public void unregisterDescriptor(
0741:                    RegistryElementDescriptor descriptor) {
0742:
0743:                if (descriptor == null)
0744:                    throw new IllegalArgumentException(JaiI18N
0745:                            .getString("Generic0"));
0746:
0747:                String descriptorName = descriptor.getName();
0748:
0749:                String[] supportedModes = descriptor.getSupportedModes();
0750:
0751:                // First make sure that all supported modes are legal registry
0752:                // modes.
0753:                for (int i = 0; i < supportedModes.length; i++) {
0754:                    if (RegistryMode.getMode(supportedModes[i]) == null)
0755:                        throw new IllegalArgumentException(JaiI18N.formatMsg(
0756:                                "OperationRegistry3", new Object[] {
0757:                                        descriptorName, supportedModes[i] }));
0758:                }
0759:
0760:                // Now unregister the descriptor against each supported mode.
0761:                for (int i = 0; i < supportedModes.length; i++) {
0762:
0763:                    DescriptorCache dc = getDescriptorCache(supportedModes[i]);
0764:
0765:                    dc.removeDescriptor(descriptor);
0766:                }
0767:            }
0768:
0769:            /**
0770:             * Get the <code>RegistryElementDescriptor</code>
0771:             * corresponding to a <code>descriptorClass</code>
0772:             * and a <code>descriptorName</code>. For example,
0773:             * <code>getDescriptor(OperationDescriptor.class, "add")</code>
0774:             * would get the operation descriptor for the "add" image operation.
0775:             * Note that different descriptors might have been registered
0776:             * against each mode associated with the descriptorClass. In this
0777:             * case this methods will arbitrarily return the first descriptor
0778:             * it encounters with a matching descriptorName and descriptorClass.
0779:             *
0780:             * @param descriptorClass the descriptor <code>Class</code>
0781:             * @param descriptorName the descriptor name as a <code>String</code>
0782:             *
0783:             * @throws IllegalArgumentException if <code>descriptorClass</code> is
0784:             *         <code>null</code> or if the <code>descriptorClass</code> is
0785:             *         not associated with any of the modes returned
0786:             *          <code>RegistryMode.getModes()</code>
0787:             * @throws IllegalArgumentException if descriptorName is <code>null</code>
0788:             *
0789:             * @since JAI 1.1
0790:             */
0791:            public RegistryElementDescriptor getDescriptor(
0792:                    Class descriptorClass, String descriptorName) {
0793:
0794:                if ((descriptorClass == null) || (descriptorName == null))
0795:                    throw new IllegalArgumentException(JaiI18N
0796:                            .getString("Generic0"));
0797:
0798:                String supportedModes[] = RegistryMode
0799:                        .getModeNames(descriptorClass);
0800:
0801:                if (supportedModes == null)
0802:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
0803:                            "OperationRegistry4",
0804:                            new Object[] { descriptorClass.getName() }));
0805:
0806:                RegistryElementDescriptor red;
0807:
0808:                // Now look for the descriptor in each supported mode.
0809:                for (int i = 0; i < supportedModes.length; i++) {
0810:
0811:                    DescriptorCache dc = getDescriptorCache(supportedModes[i]);
0812:
0813:                    if ((red = dc.getDescriptor(descriptorName)) != null)
0814:                        return red;
0815:                }
0816:
0817:                return null;
0818:            }
0819:
0820:            /**
0821:             * Get a <code>List</code> of all <code>RegistryElementDescriptor</code>
0822:             * corresponding to the <code>descriptorClass</code>. For example,
0823:             * <code>getDescriptors(OperationDescriptor.class)</code>
0824:             * would get a list of all image operation descriptors.
0825:             *
0826:             * @param descriptorClass the descriptor <code>Class</code>
0827:             *
0828:             * @throws IllegalArgumentException if <code>descriptorClass</code> is
0829:             *		<code>null</code> or if the <code>descriptorClass</code> is
0830:             *		not associated with any of the modes returned
0831:             *          <code>RegistryMode.getModes()</code>
0832:             *
0833:             * @since JAI 1.1
0834:             */
0835:            public List getDescriptors(Class descriptorClass) {
0836:
0837:                if (descriptorClass == null)
0838:                    throw new IllegalArgumentException(JaiI18N
0839:                            .getString("Generic0"));
0840:
0841:                String supportedModes[] = RegistryMode
0842:                        .getModeNames(descriptorClass);
0843:
0844:                if (supportedModes == null)
0845:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
0846:                            "OperationRegistry4",
0847:                            new Object[] { descriptorClass.getName() }));
0848:
0849:                List list;
0850:                HashSet set = new HashSet();
0851:
0852:                // Now unregister the descriptor against each supported mode.
0853:                for (int i = 0; i < supportedModes.length; i++) {
0854:
0855:                    DescriptorCache dc = getDescriptorCache(supportedModes[i]);
0856:
0857:                    if ((list = dc.getDescriptors()) != null)
0858:                        set.addAll(list);
0859:                }
0860:
0861:                return new ArrayList(set);
0862:            }
0863:
0864:            /**
0865:             * Get an array of all the descriptor names
0866:             * corresponding to the <code>descriptorClass</code>. For example,
0867:             * <code>getDescriptorNames(OperationDescriptor.class)</code>
0868:             * would get an array of all image operation descriptor names.
0869:             *
0870:             * @param descriptorClass the descriptor <code>Class</code>
0871:             *
0872:             * @throws IllegalArgumentException if <code>descriptorClass</code> is
0873:             *		<code>null</code> or if the <code>descriptorClass</code> is
0874:             *		not associated with any of the modes returned
0875:             *          <code>RegistryMode.getModes()</code>
0876:             *
0877:             * @since JAI 1.1
0878:             */
0879:            public String[] getDescriptorNames(Class descriptorClass) {
0880:
0881:                List dlist = getDescriptors(descriptorClass);
0882:
0883:                if (dlist != null) {
0884:
0885:                    Iterator diter = dlist.iterator();
0886:
0887:                    String[] names = new String[dlist.size()];
0888:                    int i = 0;
0889:
0890:                    while (diter.hasNext()) {
0891:                        RegistryElementDescriptor red = (RegistryElementDescriptor) diter
0892:                                .next();
0893:
0894:                        names[i++] = red.getName();
0895:                    }
0896:
0897:                    return names;
0898:                }
0899:
0900:                return null;
0901:            }
0902:
0903:            /**
0904:             * Get the <code>RegistryElementDescriptor</code> corresponding to
0905:             * <code>descriptorName</code> which supports the specified mode.
0906:             * This is done by matching up the <code>descriptorName</code>
0907:             * against <code>RegistryElementDescriptor.getName</code> in a
0908:             * case-insensitive manner. This returns <code>null</code> if there
0909:             * no <code>RegistryElementDescriptor</code> corresponding to
0910:             * <code>descriptorName</code> that supports the specified mode.
0911:             *
0912:             * @param modeName the registry mode name as a <code>String</code>
0913:             * @param descriptorName the descriptor name as a <code>String</code>
0914:             *
0915:             * @throws IllegalArgumentException if modeName is <code>null</code>
0916:             *          or if the modeName is not one of the modes returned
0917:             *          <code>RegistryMode.getModes()</code>
0918:             * @throws IllegalArgumentException if descriptorName is <code>null</code>
0919:             *
0920:             * @since JAI 1.1
0921:             */
0922:            public RegistryElementDescriptor getDescriptor(String modeName,
0923:                    String descriptorName) {
0924:
0925:                DescriptorCache dc = getDescriptorCache(modeName);
0926:
0927:                if (dc != null)
0928:                    return dc.getDescriptor(descriptorName);
0929:
0930:                return null;
0931:            }
0932:
0933:            /**
0934:             * Get a list of all <code>RegistryElementDescriptor</code>s registered
0935:             * under a given registry mode.
0936:             *
0937:             * @param modeName the registry mode name as a <code>String</code>
0938:             *
0939:             * @throws IllegalArgumentException if modeName is <code>null</code>
0940:             *          or if the modeName is not one of the modes returned
0941:             *          <code>RegistryMode.getModes()</code>
0942:             *
0943:             * @since JAI 1.1
0944:             */
0945:            public List getDescriptors(String modeName) {
0946:                DescriptorCache dc = getDescriptorCache(modeName);
0947:
0948:                if (dc != null)
0949:                    return dc.getDescriptors();
0950:
0951:                return null;
0952:            }
0953:
0954:            /**
0955:             * Get an array of all descriptor-names of descriptors registered
0956:             * under a given registry mode.
0957:             *
0958:             * @param modeName the registry mode name as a <code>String</code>
0959:             *
0960:             * @throws IllegalArgumentException if modeName is <code>null</code>
0961:             *          or if the modeName is not one of the modes returned
0962:             *          <code>RegistryMode.getModes()</code>
0963:             *
0964:             * @since JAI 1.1
0965:             */
0966:            public String[] getDescriptorNames(String modeName) {
0967:                DescriptorCache dc = getDescriptorCache(modeName);
0968:
0969:                if (dc != null)
0970:                    return dc.getDescriptorNames();
0971:
0972:                return null;
0973:            }
0974:
0975:            //////////////////
0976:            //
0977:            // Set of methods to set/unset/clear product preferences
0978:
0979:            /**
0980:             * Set the preference between two products for a descriptor
0981:             * registered under a registry mode.
0982:             *
0983:             * @param modeName the registry mode name as a <code>String</code>
0984:             * @param descriptorName the descriptor name as a <code>String</code>
0985:             * @param preferredProductName the product to be preferred.
0986:             * @param otherProductName the other product.
0987:             *
0988:             * @throws IllegalArgumentException if any of the arguments
0989:             *             is <code>null</code>
0990:             * @throws IllegalArgumentException if modeName is not one of
0991:             *             those returned by <code>RegistryMode.getModes()</code>
0992:             * @throws IllegalArgumentException if the registry mode does not
0993:             *		    support preferences
0994:             * @throws IllegalArgumentException if there is no <code>
0995:             *             RegistryElementDescriptor</code> registered against
0996:             *             the <code>descriptorName</code> under <code>modeName</code>.
0997:             * @throws IllegalArgumentException if either of the products are
0998:             *		    not registered against <code>descriptorName</code>
0999:             *		    under <code>productName</code>.
1000:             *
1001:             * @since JAI 1.1
1002:             */
1003:            public void setProductPreference(String modeName,
1004:                    String descriptorName, String preferredProductName,
1005:                    String otherProductName) {
1006:
1007:                DescriptorCache dc = getDescriptorCache(modeName);
1008:
1009:                if (dc != null)
1010:                    dc.setProductPreference(descriptorName,
1011:                            preferredProductName, otherProductName);
1012:            }
1013:
1014:            /**
1015:             * Remove the preference between two products for a descriptor
1016:             * registered under a registry mode.
1017:             *
1018:             * @param modeName the registry mode name as a <code>String</code>
1019:             * @param descriptorName the descriptor name as a <code>String</code>
1020:             * @param preferredProductName the product formerly preferred.
1021:             * @param otherProductName the other product.
1022:             *
1023:             * @throws IllegalArgumentException if any of the arguments
1024:             *             is <code>null</code>
1025:             * @throws IllegalArgumentException if modeName is not one of
1026:             *             those returned by <code>RegistryMode.getModes()</code>
1027:             * @throws IllegalArgumentException if the registry mode does not
1028:             *		    support preferences
1029:             * @throws IllegalArgumentException if there is no <code>
1030:             *             RegistryElementDescriptor</code> registered against
1031:             *             the <code>descriptorName</code> under <code>modeName</code>.
1032:             * @throws IllegalArgumentException if either of the products are
1033:             *		    not registered against <code>descriptorName</code>
1034:             *		    under <code>productName</code>.
1035:             *
1036:             * @since JAI 1.1
1037:             */
1038:            public void unsetProductPreference(String modeName,
1039:                    String descriptorName, String preferredProductName,
1040:                    String otherProductName) {
1041:
1042:                DescriptorCache dc = getDescriptorCache(modeName);
1043:
1044:                if (dc != null)
1045:                    dc.unsetProductPreference(descriptorName,
1046:                            preferredProductName, otherProductName);
1047:            }
1048:
1049:            /**
1050:             * Remove all the preferences between products for a descriptor
1051:             * registered under a registry mode.
1052:             *
1053:             * @param modeName the registry mode name as a <code>String</code>
1054:             * @param descriptorName the descriptor name as a <code>String</code>
1055:             *
1056:             * @throws IllegalArgumentException if modeName is <code>null</code>
1057:             *          or if the modeName is not one of the modes returned
1058:             *          <code>RegistryMode.getModes()</code>
1059:             * @throws IllegalArgumentException if descriptorName is <code>null</code>
1060:             * @throws IllegalArgumentException if the registry mode does not
1061:             *		    support preferences
1062:             *
1063:             * @since JAI 1.1
1064:             */
1065:            public void clearProductPreferences(String modeName,
1066:                    String descriptorName) {
1067:
1068:                DescriptorCache dc = getDescriptorCache(modeName);
1069:
1070:                if (dc != null)
1071:                    dc.clearProductPreferences(descriptorName);
1072:            }
1073:
1074:            /**
1075:             * Returns a list of the pairwise product preferences
1076:             * under a particular descriptor registered against a registry mode.
1077:             *
1078:             * @param modeName the registry mode name as a <code>String</code>
1079:             * @param descriptorName the descriptor name as a <code>String</code>
1080:             *
1081:             * @return an array of 2-element arrays of Strings.
1082:             *
1083:             * @throws IllegalArgumentException if modeName is <code>null</code>
1084:             *          or if the modeName is not one of the modes returned
1085:             *          <code>RegistryMode.getModes()</code>
1086:             * @throws IllegalArgumentException if descriptorName is <code>null</code>
1087:             * @throws IllegalArgumentException if the registry mode does not
1088:             *		    support preferences
1089:             *
1090:             * @since JAI 1.1
1091:             */
1092:            public String[][] getProductPreferences(String modeName,
1093:                    String descriptorName) {
1094:
1095:                DescriptorCache dc = getDescriptorCache(modeName);
1096:
1097:                if (dc != null)
1098:                    return dc.getProductPreferences(descriptorName);
1099:
1100:                return null;
1101:            }
1102:
1103:            /**
1104:             * Returns a list of the products registered under a particular
1105:             * descriptor in an ordering that satisfies all of the pairwise
1106:             * preferences that have been set. Returns <code>null</code> if
1107:             * cycles exist. Returns null if no descriptor has been registered
1108:             * under this descriptorName, or if no products exist for this
1109:             * operation.
1110:             *
1111:             * @param modeName the registry mode name as a <code>String</code>
1112:             * @param descriptorName the descriptor name as a <code>String</code>
1113:             *
1114:             * @return a <code>Vector</code> of Strings representing product names.
1115:             *
1116:             * @throws IllegalArgumentException if modeName is <code>null</code>
1117:             *          or if the modeName is not one of the modes returned
1118:             *          <code>RegistryMode.getModes()</code>
1119:             * @throws IllegalArgumentException if descriptorName is <code>null</code>
1120:             * @throws IllegalArgumentException if the registry mode does not
1121:             *		    support preferences
1122:             *
1123:             * @since JAI 1.1
1124:             */
1125:            public Vector getOrderedProductList(String modeName,
1126:                    String descriptorName) {
1127:
1128:                DescriptorCache dc = getDescriptorCache(modeName);
1129:
1130:                if (dc != null)
1131:                    return dc.getOrderedProductList(descriptorName);
1132:
1133:                return null;
1134:            }
1135:
1136:            //////////////////
1137:            //
1138:            // Set of methods to maintain factory objects to register/unregister
1139:            // & set/unset/clear preferences & get-ordered-lists of factory
1140:            // objects
1141:
1142:            /**
1143:             * Get the local name for a factory instance used in the
1144:             * DescriptorCache (to be used in writing out the registry file).
1145:             */
1146:            String getLocalName(String modeName, Object factoryInstance) {
1147:
1148:                FactoryCache fc = getFactoryCache(modeName);
1149:
1150:                if (fc != null)
1151:                    return fc.getLocalName(factoryInstance);
1152:
1153:                return null;
1154:            }
1155:
1156:            /**
1157:             * Register a factory object with a particular product and descriptor
1158:             * against a specified mode. For modes that do not support preferences
1159:             * the productName is ignored (can be <code>null</code>)
1160:             *
1161:             * @param modeName the registry mode name as a <code>String</code>
1162:             * @param descriptorName the descriptor name as a <code>String</code>
1163:             * @param productName the product name as a <code>String</code>
1164:             * @param factory the object to be registered.
1165:             *
1166:             * @throws IllegalArgumentException if any of the arguments
1167:             *             is <code>null</code> (productName can be <code>null</code>
1168:             *		    for modes that do not support preferences).
1169:             * @throws IllegalArgumentException if modeName is not one of
1170:             *             those returned by <code>RegistryMode.getModes()</code>
1171:             * @throws IllegalArgumentException if there is no <code>
1172:             *             RegistryElementDescriptor</code> registered against
1173:             *             the <code>descriptorName</code>
1174:             *
1175:             * @since JAI 1.1
1176:             */
1177:            public void registerFactory(String modeName, String descriptorName,
1178:                    String productName, Object factory) {
1179:
1180:                DescriptorCache dc = getDescriptorCache(modeName);
1181:                FactoryCache fc = getFactoryCache(modeName);
1182:
1183:                if (dc.getDescriptor(descriptorName) == null) {
1184:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
1185:                            "OperationRegistry5", new Object[] {
1186:                                    descriptorName, modeName }));
1187:                }
1188:
1189:                if (factory == null) {
1190:                    throw new IllegalArgumentException(JaiI18N
1191:                            .getString("Generic0"));
1192:                }
1193:
1194:                if (dc.arePreferencesSupported) {
1195:
1196:                    OperationGraph og = dc.addProduct(descriptorName,
1197:                            productName);
1198:
1199:                    if (og == null) {
1200:                        throw new IllegalArgumentException(JaiI18N.formatMsg(
1201:                                "OperationRegistry5", new Object[] {
1202:                                        descriptorName, modeName }));
1203:                    }
1204:
1205:                    og.addOp(new PartialOrderNode(factory, factory.getClass()
1206:                            .getName()));
1207:                }
1208:
1209:                fc.addFactory(descriptorName, productName, factory);
1210:            }
1211:
1212:            /**
1213:             * Unregister a factory object previously registered with a product
1214:             * and descriptor against the specified mode. For modes that do
1215:             * not support preferences the productName is ignored (can be
1216:             * <code>null</code>)
1217:             *
1218:             * @param modeName the registry mode name as a <code>String</code>
1219:             * @param descriptorName the descriptor name as a <code>String</code>
1220:             * @param productName the product name as a <code>String</code>
1221:             * @param factory the object to be unregistered.
1222:             *
1223:             * @throws IllegalArgumentException if any of the arguments
1224:             *             is <code>null</code> (productName can be <code>null</code>
1225:             *		    for modes that do not support preferences).
1226:             * @throws IllegalArgumentException if modeName is not one of
1227:             *             those returned by <code>RegistryMode.getModes()</code>
1228:             * @throws IllegalArgumentException if there is no <code>
1229:             *             RegistryElementDescriptor</code> registered against
1230:             *             the <code>descriptorName</code>
1231:             * @throws IllegalArgumentException if the factory object was not previously
1232:             *             registered against descriptorName and productName
1233:             *
1234:             * @since JAI 1.1
1235:             */
1236:            public void unregisterFactory(String modeName,
1237:                    String descriptorName, String productName, Object factory) {
1238:
1239:                DescriptorCache dc = getDescriptorCache(modeName);
1240:                FactoryCache fc = getFactoryCache(modeName);
1241:
1242:                if (dc.getDescriptor(descriptorName) == null) {
1243:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
1244:                            "OperationRegistry5", new Object[] {
1245:                                    descriptorName, modeName }));
1246:                }
1247:
1248:                if (factory == null) {
1249:                    throw new IllegalArgumentException(JaiI18N
1250:                            .getString("Generic0"));
1251:                }
1252:
1253:                fc.removeFactory(descriptorName, productName, factory);
1254:
1255:                if (dc.arePreferencesSupported) {
1256:
1257:                    OperationGraph og = dc.lookupProduct(descriptorName,
1258:                            productName);
1259:
1260:                    if (og == null) {
1261:                        throw new IllegalArgumentException(JaiI18N.formatMsg(
1262:                                "OperationRegistry5", new Object[] {
1263:                                        descriptorName, modeName }));
1264:                    }
1265:
1266:                    og.removeOp(factory);
1267:                }
1268:            }
1269:
1270:            /**
1271:             * Sets a preference between two factory instances for a given
1272:             * operation under a specified product.
1273:             *
1274:             * @param modeName the registry mode name as a <code>String</code>
1275:             * @param descriptorName the descriptor name as a <code>String</code>
1276:             * @param productName the product name as a <code>String</code>
1277:             * @param preferredOp the preferred factory object
1278:             * @param otherOp the other factory object
1279:             *
1280:             * @throws IllegalArgumentException if any of the arguments
1281:             *             is <code>null</code>
1282:             * @throws IllegalArgumentException if modeName is not one of
1283:             *             those returned by <code>RegistryMode.getModes()</code>
1284:             * @throws IllegalArgumentException if there is no <code>
1285:             *             RegistryElementDescriptor</code> registered against
1286:             *             the <code>descriptorName</code>
1287:             * @throws IllegalArgumentException if either of the factory objects
1288:             *             were not previously registered against
1289:             *             descriptorName and productName
1290:             * @throws IllegalArgumentException if the registry mode does not
1291:             *		    support preferences
1292:             *
1293:             * @since JAI 1.1
1294:             */
1295:            public void setFactoryPreference(String modeName,
1296:                    String descriptorName, String productName,
1297:                    Object preferredOp, Object otherOp) {
1298:
1299:                DescriptorCache dc = getDescriptorCache(modeName);
1300:                FactoryCache fc = getFactoryCache(modeName);
1301:
1302:                if (dc.getDescriptor(descriptorName) == null) {
1303:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
1304:                            "OperationRegistry5", new Object[] {
1305:                                    descriptorName, modeName }));
1306:                }
1307:
1308:                // This should throw an exception if preferences are not
1309:                // supported.
1310:                fc.setPreference(descriptorName, productName, preferredOp,
1311:                        otherOp);
1312:
1313:                if (dc.arePreferencesSupported) {
1314:
1315:                    OperationGraph og = dc.lookupProduct(descriptorName,
1316:                            productName);
1317:
1318:                    if (og == null) {
1319:                        throw new IllegalArgumentException(JaiI18N.formatMsg(
1320:                                "OperationRegistry5", new Object[] {
1321:                                        descriptorName, modeName }));
1322:                    }
1323:
1324:                    og.setPreference(preferredOp, otherOp);
1325:                }
1326:            }
1327:
1328:            /**
1329:             * Unsets a preference between two factory instances for a given
1330:             * operation under a specified product.
1331:             *
1332:             * @param modeName the registry mode name as a <code>String</code>
1333:             * @param descriptorName the descriptor name as a <code>String</code>
1334:             * @param productName the product name as a <code>String</code>
1335:             * @param preferredOp the factory object formerly preferred
1336:             * @param otherOp the other factory object
1337:             *
1338:             * @throws IllegalArgumentException if any of the arguments
1339:             *             is <code>null</code>
1340:             * @throws IllegalArgumentException if modeName is not one of
1341:             *             those returned by <code>RegistryMode.getModes()</code>
1342:             * @throws IllegalArgumentException if there is no <code>
1343:             *             RegistryElementDescriptor</code> registered against
1344:             *             the <code>descriptorName</code>
1345:             * @throws IllegalArgumentException if either of the factory objects
1346:             *             were not previously registered against
1347:             *             descriptorName and productName
1348:             * @throws IllegalArgumentException if the registry mode does not
1349:             *		    support preferences
1350:             *
1351:             * @since JAI 1.1
1352:             */
1353:            public void unsetFactoryPreference(String modeName,
1354:                    String descriptorName, String productName,
1355:                    Object preferredOp, Object otherOp) {
1356:
1357:                DescriptorCache dc = getDescriptorCache(modeName);
1358:                FactoryCache fc = getFactoryCache(modeName);
1359:
1360:                if (dc.getDescriptor(descriptorName) == null) {
1361:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
1362:                            "OperationRegistry5", new Object[] {
1363:                                    descriptorName, modeName }));
1364:                }
1365:
1366:                // This should throw an exception if preferences are not
1367:                // supported.
1368:                fc.unsetPreference(descriptorName, productName, preferredOp,
1369:                        otherOp);
1370:
1371:                if (dc.arePreferencesSupported) {
1372:
1373:                    OperationGraph og = dc.lookupProduct(descriptorName,
1374:                            productName);
1375:
1376:                    if (og == null) {
1377:                        throw new IllegalArgumentException(JaiI18N.formatMsg(
1378:                                "OperationRegistry5", new Object[] {
1379:                                        descriptorName, modeName }));
1380:                    }
1381:
1382:                    og.unsetPreference(preferredOp, otherOp);
1383:                }
1384:            }
1385:
1386:            /**
1387:             * Removes all preferences between instances of a factory
1388:             * within a product registered under a particular
1389:             * <code>OperationDescriptor</code>.
1390:             *
1391:             * @param modeName the registry mode name as a <code>String</code>
1392:             * @param descriptorName the descriptor name as a <code>String</code>
1393:             * @param productName the product name as a <code>String</code>
1394:             *
1395:             * @throws IllegalArgumentException if any of the arguments
1396:             *             is <code>null</code>
1397:             * @throws IllegalArgumentException if modeName is not one of
1398:             *             those returned by <code>RegistryMode.getModes()</code>
1399:             * @throws IllegalArgumentException if there is no <code>
1400:             *             RegistryElementDescriptor</code> registered against
1401:             *             the <code>descriptorName</code>
1402:             *
1403:             * @since JAI 1.1
1404:             */
1405:            public void clearFactoryPreferences(String modeName,
1406:                    String descriptorName, String productName) {
1407:
1408:                DescriptorCache dc = getDescriptorCache(modeName);
1409:                FactoryCache fc = getFactoryCache(modeName);
1410:
1411:                if (dc.getDescriptor(descriptorName) == null) {
1412:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
1413:                            "OperationRegistry5", new Object[] {
1414:                                    descriptorName, modeName }));
1415:                }
1416:
1417:                Object prefs[][] = fc.getPreferences(descriptorName,
1418:                        productName);
1419:
1420:                if (prefs != null) {
1421:
1422:                    OperationGraph og = dc.lookupProduct(descriptorName,
1423:                            productName);
1424:
1425:                    if (og == null) {
1426:                        throw new IllegalArgumentException(JaiI18N.formatMsg(
1427:                                "OperationRegistry5", new Object[] {
1428:                                        descriptorName, modeName }));
1429:                    }
1430:
1431:                    for (int i = 0; i < prefs.length; i++) {
1432:                        og.unsetPreference(prefs[i][0], prefs[i][1]);
1433:                    }
1434:                }
1435:
1436:                fc.clearPreferences(descriptorName, productName);
1437:            }
1438:
1439:            /**
1440:             * Get all pairwise preferences between instances of a factory
1441:             * within a product registered under a particular
1442:             * <code>OperationDescriptor</code>.
1443:             *
1444:             * @param modeName the registry mode name as a <code>String</code>
1445:             * @param descriptorName the descriptor name as a <code>String</code>
1446:             * @param productName the product name as a <code>String</code>
1447:             *
1448:             * @throws IllegalArgumentException if any of the arguments
1449:             *             is <code>null</code>
1450:             * @throws IllegalArgumentException if modeName is not one of
1451:             *             those returned by <code>RegistryMode.getModes()</code>
1452:             * @throws IllegalArgumentException if there is no <code>
1453:             *             RegistryElementDescriptor</code> registered against
1454:             *             the <code>descriptorName</code>
1455:             *
1456:             * @since JAI 1.1
1457:             */
1458:            public Object[][] getFactoryPreferences(String modeName,
1459:                    String descriptorName, String productName) {
1460:
1461:                DescriptorCache dc = getDescriptorCache(modeName);
1462:                FactoryCache fc = getFactoryCache(modeName);
1463:
1464:                if (dc.getDescriptor(descriptorName) == null) {
1465:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
1466:                            "OperationRegistry5", new Object[] {
1467:                                    descriptorName, modeName }));
1468:                }
1469:
1470:                return fc.getPreferences(descriptorName, productName);
1471:            }
1472:
1473:            /**
1474:             * Returns a list of the factory instances of a product registered
1475:             * under a particular <code>OperationDescriptor</code>, in an
1476:             * ordering that satisfies all of the pairwise preferences that
1477:             * have been set. Returns <code>null</code> if cycles exist.
1478:             * Returns <code>null</code>, if the product does not exist under
1479:             * this descriptorName.
1480:             *
1481:             * If the particular registry mode does not support preferences then the
1482:             * returned <code>List</code> will contain a single factory.
1483:             *
1484:             * @param modeName the registry mode name as a <code>String</code>
1485:             * @param descriptorName the descriptor name as a <code>String</code>
1486:             * @param productName the product name as a <code>String</code>
1487:             *
1488:             * @return an ordered <code>List</code> of factory instances
1489:             *
1490:             * @throws IllegalArgumentException if any of the arguments
1491:             *             is <code>null</code> (productName can be <code>null</code>
1492:             *		    for modes that do not support preferences).
1493:             * @throws IllegalArgumentException if modeName is not one of
1494:             *             those returned by <code>RegistryMode.getModes()</code>
1495:             * @throws IllegalArgumentException if there is no <code>
1496:             *             RegistryElementDescriptor</code> registered against
1497:             *             the <code>descriptorName</code>
1498:             *
1499:             * @since JAI 1.1
1500:             */
1501:            public List getOrderedFactoryList(String modeName,
1502:                    String descriptorName, String productName) {
1503:
1504:                DescriptorCache dc = getDescriptorCache(modeName);
1505:                FactoryCache fc = getFactoryCache(modeName);
1506:
1507:                if (dc.getDescriptor(descriptorName) == null) {
1508:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
1509:                            "OperationRegistry5", new Object[] {
1510:                                    descriptorName, modeName }));
1511:                }
1512:
1513:                if (dc.arePreferencesSupported) {
1514:
1515:                    OperationGraph og = dc.lookupProduct(descriptorName,
1516:                            productName);
1517:
1518:                    if (og == null)
1519:                        return null;
1520:
1521:                    Vector v = og.getOrderedOperationList();
1522:
1523:                    if ((v == null) || (v.size() <= 0))
1524:                        return null;
1525:
1526:                    ArrayList list = new ArrayList(v.size());
1527:
1528:                    for (int i = 0; i < v.size(); i++) {
1529:                        list.add(((PartialOrderNode) v.elementAt(i)).getData());
1530:                    }
1531:
1532:                    return list;
1533:
1534:                } else {
1535:                    return fc.getFactoryList(descriptorName, productName);
1536:                }
1537:            }
1538:
1539:            /**
1540:             * Returns an <code>Iterator</code> over all factory objects
1541:             * registered with the specified factory and operation names over
1542:             * all products. The order of objects in the iteration will be
1543:             * according to the pairwise preferences among products and image
1544:             * factories within a product. The <code>remove()</code> method
1545:             * of the <code>Iterator</code> may not be implemented. If the
1546:             * particular factory does not have preferences then the returned
1547:             * <code>Iterator</code> will traverse a collection containing the
1548:             * single factory.
1549:             *
1550:             * @param modeName the registry mode name as a <code>String</code>
1551:             * @param descriptorName the descriptor name as a <code>String</code>
1552:             *
1553:             * @return an <code>Iterator</code> over factory objects
1554:             *
1555:             * @throws IllegalArgumentException if any of the arguments
1556:             *             is <code>null</code>
1557:             * @throws IllegalArgumentException if modeName is not one of
1558:             *             those returned by <code>RegistryMode.getModes()</code>
1559:             * @throws IllegalArgumentException if there is no <code>
1560:             *             RegistryElementDescriptor</code> registered against
1561:             *             the <code>descriptorName</code>
1562:             *
1563:             * @since JAI 1.1
1564:             */
1565:            public Iterator getFactoryIterator(String modeName,
1566:                    String descriptorName) {
1567:
1568:                DescriptorCache dc = getDescriptorCache(modeName);
1569:                FactoryCache fc = getFactoryCache(modeName);
1570:
1571:                if (dc.getDescriptor(descriptorName) == null) {
1572:                    throw new IllegalArgumentException(JaiI18N.formatMsg(
1573:                            "OperationRegistry5", new Object[] {
1574:                                    descriptorName, modeName }));
1575:                }
1576:
1577:                if (dc.arePreferencesSupported) {
1578:                    Vector v = getOrderedProductList(modeName, descriptorName);
1579:
1580:                    if ((v == null) || (v.size() <= 0))
1581:                        return null;
1582:
1583:                    ArrayList list = new ArrayList();
1584:
1585:                    List plist;
1586:
1587:                    for (int i = 0; i < v.size(); i++) {
1588:                        plist = getOrderedFactoryList(modeName, descriptorName,
1589:                                (String) v.get(i));
1590:                        if (plist != null)
1591:                            list.addAll(plist);
1592:                    }
1593:
1594:                    return list.iterator();
1595:
1596:                } else {
1597:                    List list = fc.getFactoryList(descriptorName, null);
1598:
1599:                    if (list != null)
1600:                        return list.iterator();
1601:                }
1602:
1603:                return null;
1604:            }
1605:
1606:            /**
1607:             * Returns the factory of the specified type for the named
1608:             * operation. This method will return the first factory that would
1609:             * be encountered by the <code>Iterator</code> returned by the
1610:             * <code>getFactoryIterator()</code> method.
1611:             *
1612:             * @param modeName the registry mode name as a <code>String</code>
1613:             * @param descriptorName the descriptor name as a <code>String</code>
1614:             *
1615:             * @return a registered factory object
1616:             *
1617:             * @throws IllegalArgumentException if any of the arguments
1618:             *             is <code>null</code>
1619:             * @throws IllegalArgumentException if modeName is not one of
1620:             *             those returned by <code>RegistryMode.getModes()</code>
1621:             * @throws IllegalArgumentException if there is no <code>
1622:             *             RegistryElementDescriptor</code> registered against
1623:             *             the <code>descriptorName</code>
1624:             *
1625:             * @since JAI 1.1
1626:             */
1627:            public Object getFactory(String modeName, String descriptorName) {
1628:
1629:                Iterator it = getFactoryIterator(modeName, descriptorName);
1630:
1631:                if ((it != null) && it.hasNext())
1632:                    return it.next();
1633:
1634:                return null;
1635:            }
1636:
1637:            /**
1638:             * Finds the factory of the specified type for the named operation
1639:             * and invokes its default factory method with the supplied
1640:             * parameters. The class of the returned object is that of the
1641:             * object returned by the factory's object creation method.
1642:             *
1643:             * @param modeName the registry mode name as a <code>String</code>
1644:             * @param descriptorName the descriptor name as a <code>String</code>
1645:             *
1646:             * @return an object created by the factory method
1647:             *
1648:             * @throws IllegalArgumentException if modeName or descriptorName
1649:             *             is <code>null</code>
1650:             * @throws IllegalArgumentException if modeName is not one of
1651:             *             those returned by <code>RegistryMode.getModes()</code>
1652:             * @throws IllegalArgumentException if there is no <code>
1653:             *             RegistryElementDescriptor</code> registered against
1654:             *             the <code>descriptorName</code>
1655:             *
1656:             * @since JAI 1.1
1657:             */
1658:            public Object invokeFactory(String modeName, String descriptorName,
1659:                    Object[] args) {
1660:
1661:                Iterator it = getFactoryIterator(modeName, descriptorName);
1662:
1663:                if (it == null)
1664:                    return null;
1665:
1666:                FactoryCache fc = getFactoryCache(modeName);
1667:                ImagingListener listener = JAI.getDefaultInstance()
1668:                        .getImagingListener();
1669:                Exception savedOne = null;
1670:
1671:                while (it.hasNext()) {
1672:
1673:                    Object factory = it.next();
1674:                    Object obj;
1675:
1676:                    try {
1677:                        if ((obj = fc.invoke(factory, args)) != null)
1678:                            return obj;
1679:                        savedOne = null;
1680:                    } catch (Exception e) {
1681:                        listener
1682:                                .errorOccurred(JaiI18N
1683:                                        .getString("OperationRegistry6")
1684:                                        + " \"" + descriptorName + "\"", e,
1685:                                        this , false);
1686:                        savedOne = e;
1687:                        //		e.printStackTrace();
1688:                    }
1689:                }
1690:
1691:                if (savedOne != null)
1692:                    throw new ImagingException(JaiI18N
1693:                            .getString("OperationRegistry7")
1694:                            + " \"" + descriptorName + "\"", savedOne);
1695:
1696:                return null;
1697:            }
1698:
1699:            //////////////////
1700:            //
1701:            // Property related methods :
1702:            // If a RegistryElementDescriptor supports properties
1703:            // (arePropertiesSupported() return true) then a property
1704:            // environment has to be managed.
1705:            //
1706:            // In the next four methods if the mode is null then apply to all modes
1707:            // that support properties.
1708:
1709:            /**
1710:             * Adds a <code>PropertyGenerator</code> to the registry,
1711:             * associating it with a particular descriptor registered against a
1712:             * registry mode.
1713:             *
1714:             * @param modeName the registry mode name as a <code>String</code>
1715:             * @param descriptorName the descriptor name as a <code>String</code>
1716:             * @param generator the <code>PropertyGenerator</code> to be added.
1717:             *
1718:             * @throws IllegalArgumentException if any of the arguments
1719:             *             is <code>null</code>
1720:             * @throws IllegalArgumentException if modeName is not one of
1721:             *             those returned by <code>RegistryMode.getModes()</code>
1722:             * @throws IllegalArgumentException if there is no <code>
1723:             *             RegistryElementDescriptor</code> registered against
1724:             *             the <code>descriptorName</code>
1725:             * @throws IllegalArgumentException if the specified mode does not
1726:             *             support properties.
1727:             *
1728:             * @since JAI 1.1
1729:             */
1730:            public void addPropertyGenerator(String modeName,
1731:                    String descriptorName, PropertyGenerator generator) {
1732:
1733:                DescriptorCache dc = getDescriptorCache(modeName);
1734:
1735:                if (dc != null)
1736:                    dc.addPropertyGenerator(descriptorName, generator);
1737:            }
1738:
1739:            /**
1740:             * Removes a <code>PropertyGenerator</code> from its association
1741:             * with a particular descriptor/registry-mode in the registry. If
1742:             * the generator was not associated with the operation, nothing
1743:             * happens.
1744:             *
1745:             * @param modeName the registry mode name as a <code>String</code>
1746:             * @param descriptorName the descriptor name as a <code>String</code>
1747:             * @param generator the <code>PropertyGenerator</code> to be removed.
1748:             *
1749:             * @throws IllegalArgumentException if any of the arguments
1750:             *             is <code>null</code>
1751:             * @throws IllegalArgumentException if modeName is not one of
1752:             *             those returned by <code>RegistryMode.getModes()</code>
1753:             * @throws IllegalArgumentException if there is no <code>
1754:             *             RegistryElementDescriptor</code> registered against
1755:             *             the <code>descriptorName</code>
1756:             * @throws IllegalArgumentException if the specified mode does not
1757:             *             support properties.
1758:             *
1759:             * @since JAI 1.1
1760:             */
1761:            public void removePropertyGenerator(String modeName,
1762:                    String descriptorName, PropertyGenerator generator) {
1763:
1764:                DescriptorCache dc = getDescriptorCache(modeName);
1765:
1766:                if (dc != null)
1767:                    dc.removePropertyGenerator(descriptorName, generator);
1768:            }
1769:
1770:            /**
1771:             * Forces a property to be copied from the specified source by nodes
1772:             * performing a particular operation. By default, a property is
1773:             * copied from the first source node that emits it. The result of
1774:             * specifying an invalid source is undefined.
1775:             *
1776:             * @param modeName the registry mode name as a <code>String</code>
1777:             * @param descriptorName the descriptor name as a <code>String</code>
1778:             * @param propertyName the name of the property to be copied.
1779:             * @param sourceIndex the index of the source to copy the property from.
1780:             *
1781:             * @throws IllegalArgumentException if any of the <code>String</code>
1782:             *             arguments is <code>null</code>
1783:             * @throws IllegalArgumentException if modeName is not one of
1784:             *             those returned by <code>RegistryMode.getModes()</code>
1785:             * @throws IllegalArgumentException if there is no <code>
1786:             *             RegistryElementDescriptor</code> registered against
1787:             *             the <code>descriptorName</code>
1788:             * @throws IllegalArgumentException if the specified mode does not
1789:             *             support properties.
1790:             *
1791:             * @since JAI 1.1
1792:             */
1793:            public void copyPropertyFromSource(String modeName,
1794:                    String descriptorName, String propertyName, int sourceIndex) {
1795:
1796:                DescriptorCache dc = getDescriptorCache(modeName);
1797:
1798:                if (dc != null)
1799:                    dc.copyPropertyFromSource(descriptorName, propertyName,
1800:                            sourceIndex);
1801:            }
1802:
1803:            /**
1804:             * Forces a particular property to be suppressed by nodes
1805:             * performing a particular operation.  By default, properties
1806:             * are passed through operations unchanged.
1807:             *
1808:             * @param modeName the registry mode name as a <code>String</code>
1809:             * @param descriptorName the descriptor name as a <code>String</code>
1810:             * @param propertyName the name of the property to be suppressed.
1811:             *
1812:             * @throws IllegalArgumentException if any of the arguments
1813:             *             is <code>null</code>
1814:             * @throws IllegalArgumentException if modeName is not one of
1815:             *             those returned by <code>RegistryMode.getModes()</code>
1816:             * @throws IllegalArgumentException if there is no <code>
1817:             *             RegistryElementDescriptor</code> registered against
1818:             *             the <code>descriptorName</code>
1819:             * @throws IllegalArgumentException if the specified mode does not
1820:             *             support properties.
1821:             *
1822:             * @since JAI 1.1
1823:             */
1824:            public void suppressProperty(String modeName,
1825:                    String descriptorName, String propertyName) {
1826:
1827:                DescriptorCache dc = getDescriptorCache(modeName);
1828:
1829:                if (dc != null)
1830:                    dc.suppressProperty(descriptorName, propertyName);
1831:            }
1832:
1833:            /**
1834:             * Forces all properties to be suppressed by nodes performing a
1835:             * particular operation.  By default, properties are passed
1836:             * through operations unchanged.
1837:             *
1838:             * @param modeName the registry mode name as a <code>String</code>
1839:             * @param descriptorName the descriptor name as a <code>String</code>
1840:             *
1841:             * @throws IllegalArgumentException if any of the arguments
1842:             *             is <code>null</code>
1843:             * @throws IllegalArgumentException if modeName is not one of
1844:             *             those returned by <code>RegistryMode.getModes()</code>
1845:             * @throws IllegalArgumentException if there is no <code>
1846:             *             RegistryElementDescriptor</code> registered against
1847:             *             the <code>descriptorName</code>
1848:             * @throws IllegalArgumentException if the specified mode does not
1849:             *             support properties.
1850:             *
1851:             * @since JAI 1.1
1852:             */
1853:            public void suppressAllProperties(String modeName,
1854:                    String descriptorName) {
1855:
1856:                DescriptorCache dc = getDescriptorCache(modeName);
1857:
1858:                if (dc != null)
1859:                    dc.suppressAllProperties(descriptorName);
1860:            }
1861:
1862:            /**
1863:             * Removes all property associated information for this registry
1864:             * mode from this <code>OperationRegistry</code>.
1865:             *
1866:             * @param modeName the registry mode name as a <code>String</code>
1867:             *
1868:             * @throws IllegalArgumentException if modeName is null or is not one of
1869:             *             those returned by <code>RegistryMode.getModes()</code>
1870:             * @throws IllegalArgumentException if the specified mode does not
1871:             *             support properties.
1872:             *
1873:             * @since JAI 1.1
1874:             */
1875:            public void clearPropertyState(String modeName) {
1876:
1877:                DescriptorCache dc = getDescriptorCache(modeName);
1878:
1879:                if (dc != null)
1880:                    dc.clearPropertyState();
1881:            }
1882:
1883:            /**
1884:             * Returns a list of the properties generated by nodes
1885:             * implementing the descriptor associated with a particular
1886:             * descriptor Name. Returns null if no properties are
1887:             * generated.
1888:             *
1889:             * @param modeName the registry mode name as a <code>String</code>
1890:             * @param descriptorName the descriptor name as a <code>String</code>
1891:             *
1892:             * @throws IllegalArgumentException if any of the arguments
1893:             *             is <code>null</code>
1894:             * @throws IllegalArgumentException if modeName is not one of
1895:             *             those returned by <code>RegistryMode.getModes()</code>
1896:             * @throws IllegalArgumentException if there is no <code>
1897:             *             RegistryElementDescriptor</code> registered against
1898:             *             the <code>descriptorName</code>
1899:             * @throws IllegalArgumentException if the specified mode does not
1900:             *             support properties.
1901:             *
1902:             * @since JAI 1.1
1903:             */
1904:            public String[] getGeneratedPropertyNames(String modeName,
1905:                    String descriptorName) {
1906:
1907:                DescriptorCache dc = getDescriptorCache(modeName);
1908:
1909:                if (dc != null)
1910:                    return dc.getGeneratedPropertyNames(descriptorName);
1911:
1912:                return null;
1913:            }
1914:
1915:            /**
1916:             * Merge mode-specific property environment with mode-independent
1917:             * property environment of the descriptor. Array elements of
1918:             * "sources" are expected to be in the same ordering as referenced
1919:             * by the "sourceIndex" parameter of copyPropertyFromSource().
1920:             *
1921:             * @param modeName the registry mode name as a <code>String</code>
1922:             * @param descriptorName the descriptor name as a <code>String</code>
1923:             * @param op the <code>Object</code> from which properties will
1924:             *           be generated.
1925:             * @param sources the <code>PropertySource</code>s corresponding to
1926:             *     the sources of the object representing the named descriptor
1927:             *     in the indicated mode.  The supplied <code>Vector</code> may
1928:             *     be empty to indicate that there are no sources.
1929:             *
1930:             * @return A <code>PropertySource</code> which encapsulates
1931:             *     the global property environment for the object representing
1932:             *     the named descriptor in the indicated mode.
1933:             *
1934:             * @throws IllegalArgumentException if any of the arguments
1935:             *             is <code>null</code>
1936:             * @throws IllegalArgumentException if modeName is not one of
1937:             *             those returned by <code>RegistryMode.getModes()</code>
1938:             * @throws IllegalArgumentException if there is no <code>
1939:             *             RegistryElementDescriptor</code> registered against
1940:             *             the <code>descriptorName</code>
1941:             * @throws IllegalArgumentException if the specified mode does not
1942:             *             support properties.
1943:             *
1944:             * @since JAI 1.1
1945:             */
1946:            public PropertySource getPropertySource(String modeName,
1947:                    String descriptorName, Object op, Vector sources) {
1948:
1949:                DescriptorCache dc = getDescriptorCache(modeName);
1950:
1951:                if (dc != null)
1952:                    return dc.getPropertySource(descriptorName, op, sources);
1953:
1954:                return null;
1955:            }
1956:
1957:            /**
1958:             * Constructs and returns a <code>PropertySource</code> suitable for
1959:             * use by a given <code>OperationNode</code>.  The
1960:             * <code>PropertySource</code> includes properties copied from prior
1961:             * nodes as well as those generated at the node itself. Additionally,
1962:             * property suppression is taken into account. The actual
1963:             * implementation of <code>getPropertySource()</code> may make use
1964:             * of deferred execution and caching.
1965:             *
1966:             * @param op the <code>OperationNode</code> requesting its
1967:             *        <code>PropertySource</code>.
1968:             *
1969:             * @throws IllegalArgumentException if op is null.
1970:             *
1971:             * @since JAI 1.1
1972:             */
1973:            public PropertySource getPropertySource(OperationNode op) {
1974:
1975:                if (op == null)
1976:                    throw new IllegalArgumentException(JaiI18N
1977:                            .getString("Generic0"));
1978:
1979:                // Get the source Vector from the ParameterBlock.
1980:                ParameterBlock pb = op.getParameterBlock();
1981:                Vector pv = (pb == null) ? null : pb.getSources();
1982:
1983:                // If the source Vector is null, replace it by a zero-length
1984:                // Vector. This tricks the DescriptorCache into accepting the
1985:                // parameter and the PropertyEnvironment object created in
1986:                // the DescriptorCache works with either a null or zero-length
1987:                // source Vector.
1988:                if (pv == null) {
1989:                    pv = new Vector();
1990:                }
1991:
1992:                return getPropertySource(op.getRegistryModeName(), op
1993:                        .getOperationName(), op, pv);
1994:            }
1995:
1996:            /**
1997:             * Load all the "META-INF/registryFile.jai" files and then
1998:             * called the <code>updateRegistry()</code> of the registered
1999:             * service provider of <code>OperationRegistrySpi</code> found
2000:             * in the classpath corresponding to this class loader. All
2001:             * non-IO exceptions encountered while parsing the registry
2002:             * files are caught and their error messages are redirected to
2003:             * <code>System.err</code>. If <code>System.err</code> is null the
2004:             * error messages will never be seen.
2005:             *
2006:             * <p>This is a convenience method to do automatic detection in runtime
2007:             * loaded jar files
2008:             *
2009:             * <p>Note that the JAI does not keep track of which JAR files have
2010:             * their registry files loaded and/or services initialized. Hence
2011:             * if <code>registerServices</code> is called twice with the
2012:             * same ClassLoader, the loading of the registry files and/or
2013:             * initialization of the services will happen twice.
2014:             *
2015:             * @since JAI 1.1
2016:             */
2017:            public void registerServices(ClassLoader cl) throws IOException {
2018:
2019:                // First load all the REGISTRY_FILEs that are found in
2020:                // the specified class loader.
2021:                Enumeration en;
2022:
2023:                if (cl == null)
2024:                    en = ClassLoader.getSystemResources(USR_REGISTRY_FILE);
2025:                else
2026:                    en = cl.getResources(USR_REGISTRY_FILE);
2027:
2028:                while (en.hasMoreElements()) {
2029:                    URL url = (URL) en.nextElement();
2030:
2031:                    RegistryFileParser.loadOperationRegistry(this , cl, url);
2032:                }
2033:
2034:                // Now call the "updateRegistry" method for all OperationRegistry
2035:                // service providers.
2036:                Iterator spitr;
2037:
2038:                if (cl == null)
2039:                    spitr = Service.providers(OperationRegistrySpi.class);
2040:                else
2041:                    spitr = Service.providers(OperationRegistrySpi.class, cl);
2042:
2043:                while (spitr.hasNext()) {
2044:
2045:                    OperationRegistrySpi ospi = (OperationRegistrySpi) spitr
2046:                            .next();
2047:                    ospi.updateRegistry(this );
2048:                }
2049:            }
2050:
2051:            /********************** DEPRECATED METHODS *************************/
2052:
2053:            // OperationDescriptor methods
2054:            /**
2055:             * Registers an <code>OperationDescriptor</code> with the registry. Each
2056:             * operation must have an <code>OperationDescriptor</code> before
2057:             * registerRIF() may be called to add RIFs to the operation.
2058:             *
2059:             * @param odesc an <code>OperationDescriptor</code> containing information
2060:             *        about the operation.
2061:             * @param operationName the operation name as a String.
2062:             *
2063:             * @deprecated as of JAI 1.1 in favor of <code>registerDescriptor(odesc)</code>
2064:             *
2065:             * @see #registerDescriptor(RegistryElementDescriptor)
2066:             *		    registerDescriptor - for list of exceptions thrown.
2067:             */
2068:            public void registerOperationDescriptor(OperationDescriptor odesc,
2069:                    String operationName) {
2070:                registerDescriptor(odesc);
2071:            }
2072:
2073:            /**
2074:             * Unregisters an <code>OperationDescriptor</code> from the registry.
2075:             *
2076:             * @param operationName the operation name as a String.
2077:             *
2078:             * @deprecated as of JAI 1.1 in favor of <code>unregisterDescriptor(...)
2079:             *		</code> which accepts an <code>OperationDescriptor</code>
2080:             *		and not a <code>operationName</code>.
2081:             *
2082:             * @see #unregisterDescriptor(RegistryElementDescriptor)
2083:             *		unregisterDescriptor - for list of exceptions thrown.
2084:             */
2085:            public void unregisterOperationDescriptor(String operationName) {
2086:
2087:                String[] operationModes = RegistryMode
2088:                        .getModeNames(OperationDescriptor.class);
2089:
2090:                RegistryElementDescriptor red;
2091:
2092:                for (int i = 0; i < operationModes.length; i++) {
2093:                    if ((red = getDescriptor(operationModes[i], operationName)) != null)
2094:                        unregisterDescriptor(red);
2095:                }
2096:            }
2097:
2098:            /**
2099:             * Returns the <code>OperationDescriptor</code> that is currently
2100:             * registered under the given name, or null if none exists.
2101:             * Though unlikely, it is possible to have different descriptors
2102:             * registered under different modes. In this case this will
2103:             * arbitrarily return the first operation descriptor found.
2104:             *
2105:             * @param operationName the String to be queried.
2106:             * @return an <code>OperationDescriptor</code>.
2107:             *
2108:             * @throws IllegalArgumentException if operationName is null.
2109:             *
2110:             * @deprecated as of JAI 1.1 in favor of <code>getDescriptor(...)</code>
2111:             *		where the mode name is explicitly specified.
2112:             *
2113:             * @see #getDescriptor(Class, String)
2114:             */
2115:            public OperationDescriptor getOperationDescriptor(
2116:                    String operationName) {
2117:                return (OperationDescriptor) getDescriptor(
2118:                        OperationDescriptor.class, operationName);
2119:            }
2120:
2121:            /**
2122:             * Returns a Vector of all currently registered
2123:             * <code>OperationDescriptor</code>s.
2124:             *
2125:             * @return a Vector of <code>OperationDescriptor</code>s.
2126:             *
2127:             * @deprecated as of JAI 1.1 in favor of <code>getDescriptors(
2128:             *	OperationDescriptor.class)</code> which returns a <code>List</code> and
2129:             *	not a <code>Vector</code>. This is currently equivalent to
2130:             *	<code>new Vector(getDescriptors(OperationDescriptor.class))</code>
2131:             *
2132:             * @see #getDescriptors(Class)
2133:             */
2134:            public Vector getOperationDescriptors() {
2135:                List list = getDescriptors(OperationDescriptor.class);
2136:
2137:                return list == null ? null : new Vector(list);
2138:            }
2139:
2140:            /**
2141:             * Returns a list of names under which all the
2142:             * <code>OperationDescriptor</code>s in the registry are registered.
2143:             *
2144:             * @return a list of currently existing operation names.
2145:             *
2146:             * @deprecated as of JAI 1.1 in favor of <code>getDescriptorNames(
2147:             *		OperationDescriptor.class)</code>.
2148:             *
2149:             * @see #getDescriptorNames(Class)
2150:             */
2151:            public String[] getOperationNames() {
2152:                return getDescriptorNames(OperationDescriptor.class);
2153:            }
2154:
2155:            // RenderedImageFactory methods
2156:
2157:            /**
2158:             * Registers a RIF with a particular product and operation.
2159:             *
2160:             * @param operationName the operation name as a String.
2161:             * @param productName the product name, as a String.
2162:             * @param RIF the <code>RenderedImageFactory</code> to be registered.
2163:             *
2164:             * @deprecated as of JAI 1.1 in favor of <code>RIFRegistry.register(...)
2165:             *	    </code>. This is currently equivalent to <code>
2166:             *	    RIFRegistry.register(this, operationName, productName, RIF)</code>
2167:             *
2168:             * @see #registerFactory registerFactory - for list of exceptions thrown.
2169:             * @see RIFRegistry#register
2170:             */
2171:            public void registerRIF(String operationName, String productName,
2172:                    RenderedImageFactory RIF) {
2173:
2174:                registerFactory(RenderedRegistryMode.MODE_NAME, operationName,
2175:                        productName, RIF);
2176:            }
2177:
2178:            /**
2179:             * Unregisters a RIF from a particular product and operation.
2180:             *
2181:             * @param operationName the operation name as a String.
2182:             * @param productName the product name, as a String.
2183:             * @param RIF the <code>RenderedImageFactory</code> to be unregistered.
2184:             *
2185:             * @deprecated as of JAI 1.1 in favor of <code>RIFRegistry.unregister(...)
2186:             *	    </code>. This is currently equivalent to <code>
2187:             *	    RIFRegistry.unregister(this, operationName, productName, RIF)</code>
2188:             *
2189:             * @see #unregisterFactory unregisterFactory - for list of exceptions thrown.
2190:             * @see RIFRegistry#unregister
2191:             */
2192:            public void unregisterRIF(String operationName, String productName,
2193:                    RenderedImageFactory RIF) {
2194:
2195:                unregisterFactory(RenderedRegistryMode.MODE_NAME,
2196:                        operationName, productName, RIF);
2197:            }
2198:
2199:            /**
2200:             * Registers a CRIF under a particular operation.
2201:             *
2202:             * @param operationName the operation name as a String.
2203:             * @param CRIF the <code>ContextualRenderedImageFactory</code> to be
2204:             * registered.
2205:             *
2206:             * @deprecated as of JAI 1.1 in favor of <code>CRIFRegistry.register(...)
2207:             *	    </code>. This is currently equivalent to <code>
2208:             *	    CRIFRegistry.register(this, operationName, productName, CRIF)</code>
2209:             *
2210:             * @see #registerFactory registerFactory - for list of exceptions thrown.
2211:             * @see CRIFRegistry#register
2212:             */
2213:            public void registerCRIF(String operationName,
2214:                    ContextualRenderedImageFactory CRIF) {
2215:
2216:                registerFactory(RenderableRegistryMode.MODE_NAME,
2217:                        operationName, null, CRIF);
2218:            }
2219:
2220:            /**
2221:             * Unregisters a CRIF from a particular operation.
2222:             *
2223:             * @param operationName the operation name as a String.
2224:             * @param CRIF the <code>ContextualRenderedImageFactory</code> to be
2225:             * unregistered.
2226:             *
2227:             * @deprecated as of JAI 1.1 in favor of <code>CRIFRegistry.unregister(...)
2228:             *	    </code>. This is currently equivalent to <code>
2229:             *	    CRIFRegistry.unregister(this, operationName, productName, CRIF)</code>
2230:             *
2231:             * @see #unregisterFactory unregisterFactory - for list of exceptions thrown.
2232:             * @see CRIFRegistry#unregister
2233:             */
2234:            public void unregisterCRIF(String operationName,
2235:                    ContextualRenderedImageFactory CRIF) {
2236:
2237:                unregisterFactory(RenderableRegistryMode.MODE_NAME,
2238:                        operationName, null, CRIF);
2239:            }
2240:
2241:            /**
2242:             * Registers a CIF with a particular product and operation.
2243:             *
2244:             * @param operationName the operation name as a String.
2245:             * @param productName the product name, as a String.
2246:             * @param CIF the <code>CollectionImageFactory</code> to be registered.
2247:             *
2248:             * @deprecated as of JAI 1.1 in favor of <code>CIFRegistry.register(...)
2249:             *	    </code>. This is currently equivalent to <code>
2250:             *	    CIFRegistry.register(this, operationName, productName, CIF)</code>
2251:             *
2252:             * @see #registerFactory registerFactory - for list of exceptions thrown.
2253:             * @see CIFRegistry#register
2254:             */
2255:            public void registerCIF(String operationName, String productName,
2256:                    CollectionImageFactory CIF) {
2257:
2258:                registerFactory(CollectionRegistryMode.MODE_NAME,
2259:                        operationName, productName, CIF);
2260:            }
2261:
2262:            /**
2263:             * Unregisters a CIF from a particular product and operation.
2264:             *
2265:             * @param operationName the operation name as a String.
2266:             * @param productName the product name, as a String.
2267:             * @param CIF the <code>CollectionImageFactory</code> to be unregistered.
2268:             *
2269:             * @deprecated as of JAI 1.1 in favor of <code>CIFRegistry.unregister(...)
2270:             *	    </code>. This is currently equivalent to <code>
2271:             *	    CIFRegistry.unregister(this, operationName, productName, CIF)</code>
2272:             *
2273:             * @see #unregisterFactory unregisterFactory - for list of exceptions thrown.
2274:             * @see CIFRegistry#unregister
2275:             */
2276:            public void unregisterCIF(String operationName, String productName,
2277:                    CollectionImageFactory CIF) {
2278:
2279:                unregisterFactory(CollectionRegistryMode.MODE_NAME,
2280:                        operationName, productName, CIF);
2281:            }
2282:
2283:            // Product preferences
2284:
2285:            /**
2286:             * Sets a preference between two products registered under a common
2287:             * <code>OperationDescriptor</code>. Any attempt to set a preference
2288:             * between a product and itself will be ignored.
2289:             *
2290:             * @param operationName the operation name as a String.
2291:             * @param preferredProductName the product to be preferred.
2292:             * @param otherProductName the other product.
2293:             *
2294:             * @deprecated as of JAI 1.1 in favor of <code>setProductPreference(...)
2295:             *	    </code> which specifies a <code>modeName</code> also. This is
2296:             *	    currently equivalent to <code>setProductPreference("rendered",
2297:             *	    operationName, preferredProductName, otherProductName)</code>
2298:             *
2299:             * @see #setProductPreference setProductPreference - for list of exceptions thrown.
2300:             */
2301:            public void setProductPreference(String operationName,
2302:                    String preferredProductName, String otherProductName) {
2303:
2304:                setProductPreference(RenderedRegistryMode.MODE_NAME,
2305:                        operationName, preferredProductName, otherProductName);
2306:            }
2307:
2308:            /**
2309:             * Removes a preference between two products registered under
2310:             * a common <code>OperationDescriptor</code>.
2311:             *
2312:             * @param operationName the operation name as a String.
2313:             * @param preferredProductName the product formerly preferred.
2314:             * @param otherProductName the other product.
2315:             *
2316:             * @deprecated as of JAI 1.1 in favor of <code>unsetProductPreference(...)
2317:             *	    </code> which specifies a <code>modeName</code> also. This is
2318:             *	    currently equivalent to <code>unsetProductPreference("rendered",
2319:             *	    operationName, preferredProductName, otherProductName)</code>
2320:             *
2321:             * @see #unsetProductPreference unsetProductPreference - for list of exceptions thrown.
2322:             */
2323:            public void unsetProductPreference(String operationName,
2324:                    String preferredProductName, String otherProductName) {
2325:
2326:                unsetProductPreference(RenderedRegistryMode.MODE_NAME,
2327:                        operationName, preferredProductName, otherProductName);
2328:            }
2329:
2330:            /**
2331:             * Removes all preferences between products registered under
2332:             * a common <code>OperationDescriptor</code>.
2333:             *
2334:             * @param operationName the operation name as a String.
2335:             *
2336:             * @deprecated as of JAI 1.1 in favor of <code>clearProductPreferences(...)
2337:             *	    </code> which specifies a <code>modeName</code> also. This is
2338:             *	    currently equivalent to <code>
2339:             *	    clearProductPreferences("rendered", operationName)</code>
2340:             *
2341:             * @see #clearProductPreferences clearProductPreferences - for list of exceptions thrown.
2342:             */
2343:            public void clearProductPreferences(String operationName) {
2344:
2345:                clearProductPreferences(RenderedRegistryMode.MODE_NAME,
2346:                        operationName);
2347:            }
2348:
2349:            /**
2350:             * Returns a list of the pairwise product preferences
2351:             * under a particular <code>OperationDescriptor</code>. If no product
2352:             * preferences have been set, returns null.
2353:             *
2354:             * @param operationName the operation name as a String.
2355:             * @return an array of 2-element arrays of Strings.
2356:             *
2357:             * @deprecated as of JAI 1.1 in favor of <code>getProductPreferences(...)
2358:             *	    </code> which accepts a <code>modeName</code> also. This is
2359:             *	    currently equivalent to <code>
2360:             *	    getProductPreferences("rendered", operationName)</code>
2361:             *
2362:             * @see #getProductPreferences getProductPreferences - for list of exceptions thrown.
2363:             */
2364:            public String[][] getProductPreferences(String operationName) {
2365:
2366:                return getProductPreferences(RenderedRegistryMode.MODE_NAME,
2367:                        operationName);
2368:            }
2369:
2370:            /**
2371:             * Returns a list of the products registered under a particular
2372:             * <code>OperationDescriptor</code>, in an ordering that satisfies
2373:             * all of the pairwise preferences that have been set. Returns
2374:             * <code>null</code> if cycles exist. Returns <code>null</code> if
2375:             * no <code>OperationDescriptor</code> has been registered under
2376:             * this operationName, or if no products exist for this operation.
2377:             *
2378:             * @param operationName the operation name as a String.
2379:             * @return a Vector of Strings representing product names.
2380:             *
2381:             * @deprecated as of JAI 1.1 in favor of <code>getOrderedProductList(...)
2382:             *	    </code> which accepts a <code>modeName</code> also. This is
2383:             *	    currently equivalent to
2384:             *	    <code>getOrderedProductList("rendered", operationName)</code>
2385:             *
2386:             * @see #getOrderedProductList getOrderedProductList - for list of exceptions thrown.
2387:             */
2388:            public Vector getOrderedProductList(String operationName) {
2389:
2390:                return getOrderedProductList(RenderedRegistryMode.MODE_NAME,
2391:                        operationName);
2392:            }
2393:
2394:            // Operation preferences (within a product)
2395:
2396:            /**
2397:             * Sets a preference between two RIFs within the same product. Any
2398:             * attempt to set a preference between a RIF and itself will be
2399:             * ignored.
2400:             *
2401:             * @param operationName the operation name as a String.
2402:             * @param productName the name of the product.
2403:             * @param preferredRIF the preferred <code>RenderedImageFactory</code>.
2404:             * @param otherRIF the other <code>RenderedImageFactory</code>.
2405:             *
2406:             * @deprecated as of JAI 1.1 in favor of <code>RIFRegistry.setPreference(...)
2407:             *	    </code>. This is currently equivalent to <code>
2408:             *	    RIFRegistry.setPreference(this, operationName, productName,
2409:             *	    preferredRIF, otherRIF)</code>
2410:             *
2411:             * @see #setFactoryPreference setFactoryPreference - for list of exceptions thrown.
2412:             * @see RIFRegistry#setPreference
2413:             */
2414:            public void setRIFPreference(String operationName,
2415:                    String productName, RenderedImageFactory preferredRIF,
2416:                    RenderedImageFactory otherRIF) {
2417:
2418:                setFactoryPreference(RenderedRegistryMode.MODE_NAME,
2419:                        operationName, productName, preferredRIF, otherRIF);
2420:            }
2421:
2422:            /**
2423:             * Sets a preference between two CIFs within the same product. Any
2424:             * attempt to set a preference between a CIF and itself will be
2425:             * ignored.
2426:             *
2427:             * @param operationName the operation name as a String.
2428:             * @param productName the name of the product.
2429:             * @param preferredCIF the preferred CollectionRenderedImageFactory.
2430:             * @param otherCIF the other CollectionRenderedImageFactory.
2431:             *
2432:             * @deprecated as of JAI 1.1 in favor of <code>CIFRegistry.setPreference(...)
2433:             *	    </code>. This is currently equivalent to <code>
2434:             *	    CIFRegistry.setPreference(this, operationName, productName,
2435:             *	    preferredCIF, otherCIF)</code>
2436:             *
2437:             * @see #setFactoryPreference setFactoryPreference - for list of exceptions thrown.
2438:             * @see CIFRegistry#setPreference
2439:             */
2440:            public void setCIFPreference(String operationName,
2441:                    String productName, CollectionImageFactory preferredCIF,
2442:                    CollectionImageFactory otherCIF) {
2443:
2444:                setFactoryPreference(CollectionRegistryMode.MODE_NAME,
2445:                        operationName, productName, preferredCIF, otherCIF);
2446:            }
2447:
2448:            /**
2449:             * Removes a preference between two RIFs within the same product.
2450:             *
2451:             * @param operationName the operation name as a String.
2452:             * @param productName the name of the product.
2453:             * @param preferredRIF the formerly preferred
2454:             *        <code>RenderedImageFactory</code>.
2455:             * @param otherRIF the other <code>RenderedImageFactory</code>.
2456:             *
2457:             * @deprecated as of JAI 1.1 in favor of <code>RIFRegistry.unsetPreference(...)
2458:             *	    </code>. This is currently equivalent to <code>
2459:             *	    RIFRegistry.unsetPreference(this, operationName, productName,
2460:             *	    preferredRIF, otherRIF)</code>
2461:             *
2462:             * @see #unsetFactoryPreference unsetFactoryPreference - for list of exceptions thrown.
2463:             * @see RIFRegistry#unsetPreference
2464:             */
2465:            public void unsetRIFPreference(String operationName,
2466:                    String productName, RenderedImageFactory preferredRIF,
2467:                    RenderedImageFactory otherRIF) {
2468:
2469:                unsetFactoryPreference(RenderedRegistryMode.MODE_NAME,
2470:                        operationName, productName, preferredRIF, otherRIF);
2471:            }
2472:
2473:            /**
2474:             * Removes a preference between two CIFs within the same product.
2475:             *
2476:             * @param operationName the operation name as a String.
2477:             * @param productName the name of the product.
2478:             * @param preferredCIF the formerly preferred
2479:             *        <code>CollectionImageFactory</code>.
2480:             * @param otherCIF the other <code>CollectionImageFactory</code>.
2481:             *
2482:             * @deprecated as of JAI 1.1 in favor of <code>CIFRegistry.unsetPreference(...)
2483:             *	    </code>. This is currently equivalent to <code>
2484:             *	    CIFRegistry.unsetPreference(this, operationName, productName,
2485:             *	    preferredCIF, otherCIF)</code>
2486:             *
2487:             * @see #unsetFactoryPreference unsetFactoryPreference - for list of exceptions thrown.
2488:             * @see CIFRegistry#unsetPreference
2489:             */
2490:            public void unsetCIFPreference(String operationName,
2491:                    String productName, CollectionImageFactory preferredCIF,
2492:                    CollectionImageFactory otherCIF) {
2493:
2494:                unsetFactoryPreference(CollectionRegistryMode.MODE_NAME,
2495:                        operationName, productName, preferredCIF, otherCIF);
2496:            }
2497:
2498:            /**
2499:             * Removes all preferences between RIFs within a product
2500:             * registered under a particular <code>OperationDescriptor</code>.
2501:             *
2502:             * @param operationName the operation name as a String.
2503:             * @param productName the name of the product.
2504:             *
2505:             * @deprecated as of JAI 1.1 in favor of <code>RIFRegistry.clearPreferences(...)
2506:             *	    </code>. This is currently equivalent to <code>
2507:             *	    RIFRegistry.clearPreferences(this, operationName, productName)</code>
2508:             *
2509:             * @see #clearFactoryPreferences clearFactoryPreferences - for list of exceptions thrown.
2510:             * @see RIFRegistry#clearPreferences
2511:             */
2512:            public void clearRIFPreferences(String operationName,
2513:                    String productName) {
2514:
2515:                clearFactoryPreferences(RenderedRegistryMode.MODE_NAME,
2516:                        operationName, productName);
2517:            }
2518:
2519:            /**
2520:             * Removes all preferences between CIFs within a product
2521:             * registered under a particular <code>OperationDescriptor</code>.
2522:             *
2523:             * @param operationName the operation name as a String.
2524:             * @param productName the name of the product.
2525:             *
2526:             * @deprecated as of JAI 1.1 in favor of <code>CIFRegistry.clearPreferences(...)
2527:             *	    </code>. This is currently equivalent to <code>
2528:             *	    CIFRegistry.clearPreferences(this, operationName, productName)</code>
2529:             *
2530:             * @see #clearFactoryPreferences clearFactoryPreferences - for list of exceptions thrown.
2531:             * @see CIFRegistry#clearPreferences
2532:             */
2533:            public void clearCIFPreferences(String operationName,
2534:                    String productName) {
2535:
2536:                clearFactoryPreferences(CollectionRegistryMode.MODE_NAME,
2537:                        operationName, productName);
2538:            }
2539:
2540:            /**
2541:             * Removes all RIF and CIF preferences within a product
2542:             * registered under a particular <code>OperationDescriptor</code>.
2543:             *
2544:             * @param operationName the operation name as a String.
2545:             * @param productName the name of the product.
2546:             *
2547:             * @deprecated as of JAI 1.1 in favor of calling <code>
2548:             *	    *IFRegistry.clearPreferences(..)</code> on all image operation
2549:             *	    related modes.
2550:             *
2551:             * @see #clearFactoryPreferences clearFactoryPreferences - for list of exceptions thrown.
2552:             * @see RIFRegistry#clearPreferences
2553:             * @see CIFRegistry#clearPreferences
2554:             */
2555:            public void clearOperationPreferences(String operationName,
2556:                    String productName) {
2557:
2558:                String[] operationModes = RegistryMode
2559:                        .getModeNames(OperationDescriptor.class);
2560:
2561:                for (int i = 0; i < operationModes.length; i++) {
2562:
2563:                    DescriptorCache dc = getDescriptorCache(operationModes[i]);
2564:
2565:                    if (!dc.arePreferencesSupported)
2566:                        continue;
2567:
2568:                    if (getDescriptor(operationModes[i], operationName) == null)
2569:                        continue;
2570:
2571:                    clearFactoryPreferences(operationModes[i], operationName,
2572:                            productName);
2573:                }
2574:            }
2575:
2576:            /**
2577:             * Returns a list of the RIFs of a product registered under a
2578:             * particular <code>OperationDescriptor</code>, in an ordering
2579:             * that satisfies all of the pairwise preferences that have
2580:             * been set. Returns <code>null</code> if cycles exist. Returns
2581:             * <code>null</code>, if the product does not exist under this
2582:             * operationName.
2583:             *
2584:             * @param operationName the operation name as a String.
2585:             * @param productName the name of the product.
2586:             * @return a Vector of RIFs.
2587:             *
2588:             * @deprecated as of JAI 1.1 in favor of <code>RIFRegistry.getOrderedList(...)
2589:             *	    </code> which returns a <code>List</code> and not a
2590:             *	    <code>Vector</code>. This is currently equivalent to <code>
2591:             *	    new Vector(RIFRegistry.getOrderedList(this, operationName,
2592:             *	    productName))</code>
2593:             *
2594:             * @see #getOrderedFactoryList getOrderedFactoryList - for list of exceptions thrown.
2595:             * @see RIFRegistry#getOrderedList
2596:             */
2597:            public Vector getOrderedRIFList(String operationName,
2598:                    String productName) {
2599:
2600:                List list = getOrderedFactoryList(
2601:                        RenderedRegistryMode.MODE_NAME, operationName,
2602:                        productName);
2603:
2604:                return list == null ? null : new Vector(list);
2605:            }
2606:
2607:            /**
2608:             * Returns a list of the CIFs of a product registered under a
2609:             * particular <code>OperationDescriptor</code>, in an ordering
2610:             * that satisfies all of the pairwise preferences that have
2611:             * been set. Returns <code>null</code> if cycles exist. Returns
2612:             * <code>null</code>, if the product does not exist under this
2613:             * operationName.
2614:             *
2615:             * @param operationName the operation name as a String.
2616:             * @param productName the name of the product.
2617:             * @return a Vector of CIFs.
2618:             *
2619:             * @deprecated as of JAI 1.1 in favor of <code>CIFRegistry.getOrderedList(...)
2620:             *	    </code> which returns a <code>List</code> and not a
2621:             *	    <code>Vector</code>. This is currently equivalent to <code>
2622:             *	    new Vector(CIFRegistry.getOrderedList(this, operationName,
2623:             *	    productName))</code>
2624:             *
2625:             * @see #getOrderedFactoryList getOrderedFactoryList - for list of exceptions thrown.
2626:             * @see CIFRegistry#getOrderedList
2627:             */
2628:            public Vector getOrderedCIFList(String operationName,
2629:                    String productName) {
2630:
2631:                List list = getOrderedFactoryList(
2632:                        CollectionRegistryMode.MODE_NAME, operationName,
2633:                        productName);
2634:
2635:                return list == null ? null : new Vector(list);
2636:            }
2637:
2638:            // Create methods
2639:
2640:            /**
2641:             * Constructs a PlanarImage (usually a <code>RenderedOp</code>) representing
2642:             * the results of applying a given operation to a particular
2643:             * ParameterBlock and rendering hints.  The registry is used to
2644:             * determine the RIF to be used to instantiate the operation.
2645:             *
2646:             * <p> If none of the RIFs registered with this
2647:             * <code>OperationRegistry</code> returns a non-null value, null is
2648:             * returned.  Exceptions thrown by the RIFs will be caught by this
2649:             * method and will not be propagated.
2650:             *
2651:             * @param operationName the operation name as a String.
2652:             * @param paramBlock the operation's ParameterBlock.
2653:             * @param renderHints a RenderingHints object containing rendering hints.
2654:             *
2655:             * @throws IllegalArgumentException if operationName is null.
2656:             *
2657:             * @deprecated as of JAI 1.1 in favor of <code>RIFRegistry.create(...)
2658:             *	    </code> which returns a <code>RenderedImage</code> and not a
2659:             *	    <code>PlanarImage</code>. This is currently equivalent to <code>
2660:             *	    PlanarImage.wrapRenderedImage(RIFRegistry.create(this,
2661:             *	    operationName, paramBlock, renderHints))</code>
2662:             *
2663:             * @see RIFRegistry#create
2664:             */
2665:            public PlanarImage create(String operationName,
2666:                    ParameterBlock paramBlock, RenderingHints renderHints) {
2667:                return PlanarImage.wrapRenderedImage(RIFRegistry.create(this ,
2668:                        operationName, paramBlock, renderHints));
2669:            }
2670:
2671:            /**
2672:             * Constructs the CRIF to be used to instantiate the operation.
2673:             * Returns null, if no CRIF is registered with the given operation
2674:             * name.
2675:             *
2676:             * @param operationName the operation name as a String.
2677:             * @param paramBlock    the operation's ParameterBlock.
2678:             *
2679:             * @throws IllegalArgumentException if operationName is null.
2680:             *
2681:             * @deprecated as of JAI 1.1 in favor of <code>CRIFRegistry.get(...)</code>
2682:             *	    This is currently equivalent to <code>CRIFRegistry.get(this,
2683:             *	    operationName)</code>
2684:             *
2685:             * @see CRIFRegistry#get
2686:             */
2687:            public ContextualRenderedImageFactory createRenderable(
2688:                    String operationName, ParameterBlock paramBlock) {
2689:
2690:                return CRIFRegistry.get(this , operationName);
2691:            }
2692:
2693:            /**
2694:             * Constructs a <code>CollectionImage</code> (usually a
2695:             * <code>CollectionOp</code>) representing the results of applying
2696:             * a given operation to a particular ParameterBlock and rendering hints.
2697:             * The registry is used to determine the CIF to be used to instantiate
2698:             * the operation.
2699:             *
2700:             * <p> If none of the CIFs registered with this
2701:             * <code>OperationRegistry</code> returns a non-null value, null is
2702:             * returned.  Exceptions thrown by the CIFs will be caught by this
2703:             * method and will not be propagated.
2704:             *
2705:             * @param operationName  The operation name as a String.
2706:             * @param args  The operation's input parameters.
2707:             * @param hints  A RenderingHints object containing rendering hints.
2708:             *
2709:             * @throws IllegalArgumentException if operationName is null.
2710:             *
2711:             * @deprecated as of JAI 1.1 in favor of <code>CIFRegistry.create(...)
2712:             *	    </code>. This is currently equivalent to <code>
2713:             *	    CIFRegistry.create(this, operationName, args, hints))</code>
2714:             *
2715:             * @see CIFRegistry#create
2716:             */
2717:            public CollectionImage createCollection(String operationName,
2718:                    ParameterBlock args, RenderingHints hints) {
2719:                return CIFRegistry.create(this , operationName, args, hints);
2720:            }
2721:
2722:            // Property management
2723:
2724:            /**
2725:             * Removes all property associated information from this
2726:             * <code>OperationRegistry</code>.
2727:             *
2728:             * @deprecated as of JAI 1.1 in factor of the version where the modeName
2729:             *	is explicitly specified. This is currently equivalent to <code>
2730:             *	clearPropertyState("rendered")</code>
2731:             *
2732:             * @see #clearPropertyState
2733:             */
2734:            public void clearPropertyState() {
2735:
2736:                clearPropertyState(RenderedRegistryMode.MODE_NAME);
2737:            }
2738:
2739:            /**
2740:             * Adds a <code>PropertyGenerator</code> to the registry, associating
2741:             * it with a particular <code>OperationDescriptor</code>.
2742:             *
2743:             * @param operationName the operation name as a String.
2744:             * @param generator the <code>PropertyGenerator</code> to be added.
2745:             *
2746:             * @deprecated as of JAI 1.1 in favor of the version where the
2747:             *	    modeName is explicitly specified. This is currently
2748:             *	    equivalent to <code>addPropertyGenerator("rendered", ...)</code>
2749:             *
2750:             * @see #addPropertyGenerator addPropertyGenerator - for list of exceptions thrown.
2751:             */
2752:            public void addPropertyGenerator(String operationName,
2753:                    PropertyGenerator generator) {
2754:
2755:                addPropertyGenerator(RenderedRegistryMode.MODE_NAME,
2756:                        operationName, generator);
2757:            }
2758:
2759:            /**
2760:             * Removes a <code>PropertyGenerator</code> from its association with a
2761:             * particular <code>OperationDescriptor</code> in the registry.  If
2762:             * the generator was not associated with the operation,
2763:             * nothing happens.
2764:             *
2765:             * @param operationName the operation name as a String.
2766:             * @param generator the <code>PropertyGenerator</code> to be removed.
2767:             *
2768:             * @deprecated as of JAI 1.1 in favor of the version where the
2769:             *	    modeName is explicitly specified. This is currently
2770:             *	    equivalent to <code>removePropertyGenerator("rendered", ...)</code>
2771:             *
2772:             * @see #removePropertyGenerator removePropertyGenerator - for list of exceptions thrown.
2773:             */
2774:            public void removePropertyGenerator(String operationName,
2775:                    PropertyGenerator generator) {
2776:
2777:                removePropertyGenerator(RenderedRegistryMode.MODE_NAME,
2778:                        operationName, generator);
2779:            }
2780:
2781:            /**
2782:             * Forces a particular property to be suppressed by nodes
2783:             * performing a particular operation.  By default, properties
2784:             * are passed through operations unchanged.
2785:             *
2786:             * @param operationName the operation name as a String.
2787:             * @param propertyName the name of the property to be suppressed.
2788:             *
2789:             * @deprecated as of JAI 1.1 in favor of the version where the
2790:             *	    modeName is explicitly specified. This is currently
2791:             *	    equivalent to <code>suppressProperty("rendered", ...)</code>
2792:             *
2793:             * @see #suppressProperty suppressProperty - for list of exceptions thrown.
2794:             */
2795:            public void suppressProperty(String operationName,
2796:                    String propertyName) {
2797:
2798:                suppressProperty(RenderedRegistryMode.MODE_NAME, operationName,
2799:                        propertyName);
2800:            }
2801:
2802:            /**
2803:             * Forces all properties to be suppressed by nodes performing a
2804:             * particular operation.  By default, properties are passed
2805:             * through operations unchanged.
2806:             *
2807:             * @param operationName the operation name as a String.
2808:             *
2809:             * @deprecated as of JAI 1.1 in favor of the version where the
2810:             *	    modeName is explicitly specified. This is currently
2811:             *	    equivalent to <code>suppressAllProperties("rendered", ...)</code>
2812:             *
2813:             * @see #suppressAllProperties suppressAllProperties - for list of exceptions thrown.
2814:             */
2815:            public void suppressAllProperties(String operationName) {
2816:
2817:                suppressAllProperties(RenderedRegistryMode.MODE_NAME,
2818:                        operationName);
2819:            }
2820:
2821:            /**
2822:             * Forces a property to be copied from the specified source image
2823:             * by <code>RenderedOp</code> nodes performing a particular
2824:             * operation.  By default, a property is copied from the first
2825:             * source node that emits it. The result of specifying an invalid
2826:             * source is undefined.
2827:             *
2828:             * @param operationName the operation name as a String.
2829:             * @param propertyName the name of the property to be copied.
2830:             * @param sourceIndex the index of the source to copy the property from.
2831:             *
2832:             * @deprecated as of JAI 1.1 in favor of the version where the
2833:             *	    modeName is explicitly specified. This is currently
2834:             *	    equivalent to <code>copyPropertyFromSource("rendered", ...)</code>
2835:             *
2836:             * @see #copyPropertyFromSource copyPropertyFromSource - for list of exceptions thrown.
2837:             */
2838:            public void copyPropertyFromSource(String operationName,
2839:                    String propertyName, int sourceIndex) {
2840:
2841:                copyPropertyFromSource(RenderedRegistryMode.MODE_NAME,
2842:                        operationName, propertyName, sourceIndex);
2843:            }
2844:
2845:            /**
2846:             * Returns a list of the properties generated by nodes
2847:             * implementing the operation associated with a particular
2848:             * Operation Name. Returns null if no properties are
2849:             * generated.
2850:             *
2851:             * @param operationName the operation name as a String.
2852:             * @return an array of Strings.
2853:             *
2854:             * @deprecated as of JAI 1.1 in favor of the version where the
2855:             *	    modeName is explicitly specified. This is currently
2856:             *	    equivalent to <code>getGeneratedPropertyNames("rendered", ...)</code>
2857:             *
2858:             * @see #getGeneratedPropertyNames getGeneratedPropertyNames - for list of exceptions thrown.
2859:             */
2860:            public String[] getGeneratedPropertyNames(String operationName) {
2861:
2862:                return getGeneratedPropertyNames(
2863:                        RenderedRegistryMode.MODE_NAME, operationName);
2864:            }
2865:
2866:            /**
2867:             * Constructs and returns a <code>PropertySource</code> suitable for
2868:             * use by a given <code>RenderedOp</code>.  The
2869:             * <code>PropertySource</code> includes properties copied from prior
2870:             * nodes as well as those generated at the node itself. Additionally,
2871:             * property suppression is taken into account. The actual
2872:             * implementation of <code>getPropertySource()</code> may make use
2873:             * of deferred execution and caching.
2874:             *
2875:             * @param op the <code>RenderedOp</code> requesting its
2876:             *        <code>PropertySource</code>.
2877:             *
2878:             * @deprecated as of JAI 1.1 in favor
2879:             *	    <code>RIFRegistry.getPropertySource(op)</code>
2880:             *
2881:             * @see RIFRegistry#getPropertySource #getPropertySource - for list of exceptions thrown.
2882:             */
2883:            public PropertySource getPropertySource(RenderedOp op) {
2884:
2885:                return RIFRegistry.getPropertySource(op);
2886:            }
2887:
2888:            /**
2889:             * Constructs and returns a <code>PropertySource</code> suitable for
2890:             * use by a given <code>RenderableOp</code>.  The
2891:             * <code>PropertySource</code> includes properties copied from prior
2892:             * nodes as well as those generated at the node itself. Additionally,
2893:             * property suppression is taken into account. The actual implementation
2894:             * of <code>getPropertySource()</code> may make use of deferred
2895:             * execution and caching.
2896:             *
2897:             * @param op the <code>RenderableOp</code> requesting its
2898:             *        <code>PropertySource</code>.
2899:             *
2900:             * @deprecated as of JAI 1.1 in favor
2901:             *	    <code>CRIFRegistry.getPropertySource(op)</code>
2902:             *
2903:             * @see CRIFRegistry#getPropertySource
2904:             */
2905:            public PropertySource getPropertySource(RenderableOp op) {
2906:
2907:                return CRIFRegistry.getPropertySource(op);
2908:            }
2909:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.