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>, §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: }
|