001: /*
002: * $RCSfile: TileDecoderRegistry.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:57:49 $
010: * $State: Exp $
011: */package javax.media.jai.registry;
012:
013: import java.awt.Point;
014: import java.awt.image.Raster;
015: import java.awt.image.SampleModel;
016: import java.io.InputStream;
017: import java.io.IOException;
018: import java.util.Iterator;
019: import java.util.List;
020: import javax.media.jai.JAI;
021: import javax.media.jai.OperationRegistry;
022: import javax.media.jai.tilecodec.TileCodecParameterList;
023: import javax.media.jai.tilecodec.TileDecoder;
024: import javax.media.jai.tilecodec.TileDecoderFactory;
025:
026: /**
027: * Utility class to provide type-safe interaction with the
028: * <code>OperationRegistry</code> for <code>TileDecoderFactory</code> objects.
029: *
030: * If the <code>OperationRegistry</code> specified as an argument to the
031: * methods in this class is null, then <code>JAI.getOperationRegistry()</code>
032: * will be used.
033: *
034: * @since JAI 1.1
035: */
036: public final class TileDecoderRegistry {
037:
038: private static final String MODE_NAME = TileDecoderRegistryMode.MODE_NAME;
039:
040: /**
041: * Registers the given <code>TileDecoderFactory</code> with the given
042: * <code>OperationRegistry</code> under the given formatName and
043: * productName.
044: *
045: * @param registry The <code>OperationRegistry</code> to register the
046: * <code>TileDecoderFactory</code> with. If this is
047: * <code>null</code>, then <code>
048: * JAI.getDefaultInstance().getOperationRegistry()</code>
049: * will be used.
050: * @param formatName The formatName to register the
051: * <code>TileDecoderFactory</code> under.
052: * @param productName The productName to register the
053: * <code>TileDecoderFactory</code> under.
054: * @param tdf The <code>TileDecoderFactory</code> to register.
055: *
056: * @throws IllegalArgumentException if formatName is null.
057: * @throws IllegalArgumentException if productName is null.
058: * @throws IllegalArgumentException if tdf is null.
059: * @throws IllegalArgumentException if there is no
060: * <code>TileCodecDescriptor</code> registered against the
061: * given <code>formatName</code>
062: */
063: public static void register(OperationRegistry registry,
064: String formatName, String productName,
065: TileDecoderFactory tdf) {
066:
067: registry = (registry != null) ? registry : JAI
068: .getDefaultInstance().getOperationRegistry();
069:
070: registry.registerFactory(MODE_NAME, formatName, productName,
071: tdf);
072: }
073:
074: /**
075: * Unregisters the given <code>TileDecoderFactory</code> previously
076: * registered under the given formatName and productName in the given
077: * <code>OperationRegistry</code>.
078: *
079: * @param registry The <code>OperationRegistry</code> to unregister the
080: * <code>TileDecoderFactory</code> from. If this is
081: * <code>null</code>, then <code>
082: * JAI.getDefaultInstance().getOperationRegistry()</code>
083: * will be used.
084: * @param formatName The formatName to unregister the
085: * <code>TileDecoderFactory</code> from.
086: * @param productName The productName to unregister the
087: * <code>TileDecoderFactory</code> from.
088: * @param tdf The <code>TileDecoderFactory</code> to unregister.
089: *
090: * @throws IllegalArgumentException if formatName is null.
091: * @throws IllegalArgumentException if productName is null.
092: * @throws IllegalArgumentException if tdf is null.
093: * @throws IllegalArgumentException if there is no
094: * <code>TileCodecDescriptor</code> registered against the
095: * given <code>formatName</code>
096: * @throws IllegalArgumentException if the tdf was not previously
097: * registered against the given formatName and productName.
098: */
099: public static void unregister(OperationRegistry registry,
100: String formatName, String productName,
101: TileDecoderFactory tdf) {
102:
103: registry = (registry != null) ? registry : JAI
104: .getDefaultInstance().getOperationRegistry();
105:
106: registry.unregisterFactory(MODE_NAME, formatName, productName,
107: tdf);
108: }
109:
110: /**
111: * Sets a preference between the given two <code>TileDecoderFactory</code>
112: * objects in the given <code>OperationRegistry</code> under the given
113: * formatName and productName.
114: *
115: * @param registry The <code>OperationRegistry</code> to set
116: * preferences on. If this is
117: * <code>null</code>, then <code>
118: * JAI.getDefaultInstance().getOperationRegistry()</code>
119: * will be used.
120: * @param formatName The formatName of the two
121: * <code>TileDecoderFactory</code>s.
122: * @param productName The productName of the two
123: * <code>TileDecoderFactory</code>s.
124: * @param preferredTDF The preferred <code>TileDecoderFactory</code>.
125: * @param otherTDF The other <code>TileDecoderFactory</code>.
126: *
127: * @throws IllegalArgumentException if formatName is null.
128: * @throws IllegalArgumentException if productName is null.
129: * @throws IllegalArgumentException if preferredTDF is null.
130: * @throws IllegalArgumentException if otherTDF is null.
131: * @throws IllegalArgumentException if there is no
132: * <code>TileCodecDescriptor</code> registered against the
133: * given <code>formatName</code>
134: * @throws IllegalArgumentException if either of the two tdf's was
135: * not previously registered against the given formatName and productName.
136: */
137: public static void setPreference(OperationRegistry registry,
138: String formatName, String productName,
139: TileDecoderFactory preferredTDF, TileDecoderFactory otherTDF) {
140:
141: registry = (registry != null) ? registry : JAI
142: .getDefaultInstance().getOperationRegistry();
143:
144: registry.setFactoryPreference(MODE_NAME, formatName,
145: productName, preferredTDF, otherTDF);
146: }
147:
148: /**
149: * Unsets a preference previously set amongst the given two
150: * <code>TileDecoderFactory</code> objects in the given
151: * <code>OperationRegistry</code> under the given formatName
152: * and productName.
153: *
154: * @param registry The <code>OperationRegistry</code> to unset
155: * preferences on. If this is
156: * <code>null</code>, then <code>
157: * JAI.getDefaultInstance().getOperationRegistry()</code>
158: * will be used.
159: * @param formatName The formatName of the two
160: * <code>TileDecoderFactory</code>s.
161: * @param productName The productName of the two
162: * <code>TileDecoderFactory</code>s.
163: * @param preferredTDF The preferred <code>TileDecoderFactory</code>.
164: * @param otherTDF The other <code>TileDecoderFactory</code>.
165: *
166: * @throws IllegalArgumentException if formatName is null.
167: * @throws IllegalArgumentException if productName is null.
168: * @throws IllegalArgumentException if preferredTDF is null.
169: * @throws IllegalArgumentException if otherTDF is null.
170: * @throws IllegalArgumentException if there is no
171: * <code>TileCodecDescriptor</code> registered against the
172: * given <code>formatName</code>
173: * @throws IllegalArgumentException if either of the two tdf's was
174: * not previously registered against the given formatName and productName.
175: */
176: public static void unsetPreference(OperationRegistry registry,
177: String formatName, String productName,
178: TileDecoderFactory preferredTDF, TileDecoderFactory otherTDF) {
179:
180: registry = (registry != null) ? registry : JAI
181: .getDefaultInstance().getOperationRegistry();
182:
183: registry.unsetFactoryPreference(MODE_NAME, formatName,
184: productName, preferredTDF, otherTDF);
185: }
186:
187: /**
188: * Clears all preferences set for registered
189: * <code>TileDecoderFactory</code>s under the given formatName and
190: * productName in the given <code>OperationRegistry</code>.
191: *
192: * @param registry The <code>OperationRegistry</code> to clear
193: * preferences from. If this is
194: * <code>null</code>, then <code>
195: * JAI.getDefaultInstance().getOperationRegistry()</code>
196: * will be used.
197: * @param formatName The format name to clear preferences under.
198: * @param productName The productName to clear preferences under.
199: *
200: * @throws IllegalArgumentException if formatName is null.
201: * @throws IllegalArgumentException if productName is null.
202: * @throws IllegalArgumentException if there is no
203: * <code>TileCodecDescriptor</code> registered against the
204: * given <code>formatName</code>.
205: */
206: public static void clearPreferences(OperationRegistry registry,
207: String formatName, String productName) {
208:
209: registry = (registry != null) ? registry : JAI
210: .getDefaultInstance().getOperationRegistry();
211:
212: registry.clearFactoryPreferences(MODE_NAME, formatName,
213: productName);
214: }
215:
216: /**
217: * Returns a List of the <code>TileDecoderFactory</code>s registered
218: * in the given <code>OperationRegistry</code> under the given
219: * formatName and productName, in an ordering that satisfies
220: * all of the pairwise preferences that have been set. Returns
221: * <code>null</code> if cycles exist.
222: *
223: * @param registry The <code>OperationRegistry</code> to clear
224: * preferences from. If this is
225: * <code>null</code>, then <code>
226: * JAI.getDefaultInstance().getOperationRegistry()</code>
227: * will be used.
228: * @param formatName The format name to clear preferences under.
229: * @param productName The productName to clear preferences under.
230: *
231: * @throws IllegalArgumentException if formatName is null.
232: * @throws IllegalArgumentException if productName is null.
233: * @throws IllegalArgumentException if there is no
234: * <code>TileCodecDescriptor</code> registered against the
235: * given <code>formatName</code>.
236: */
237: public static List getOrderedList(OperationRegistry registry,
238: String formatName, String productName) {
239:
240: registry = (registry != null) ? registry : JAI
241: .getDefaultInstance().getOperationRegistry();
242:
243: return registry.getOrderedFactoryList(MODE_NAME, formatName,
244: productName);
245: }
246:
247: /**
248: * Returns an <code>Iterator</code> over all
249: * <code>TileDecoderFactory</code> objects registered under the
250: * given format name over all products. The order of the
251: * <code>TileDecoderFactory</code> objects in the iteration will
252: * be according to the pairwise preferences among products and
253: * <code>TileDecoderFactory</code> objects within a product. The
254: * <code>remove()</code> method of the <code>Iterator</code>
255: * may not be implemented.
256: *
257: * @param registry The <code>OperationRegistry</code> to use. If
258: * this is <code>null</code>, then <code>
259: * JAI.getDefaultInstance().getOperationRegistry()</code>
260: * will be used.
261: * @param formatName The format name.
262: *
263: * @return an <code>Iterator</code> over <code>TileDecoderFactory</code>
264: * objects.
265: *
266: * @throws IllegalArgumentException if formatName is <code>null</code>
267: * @throws IllegalArgumentException if there is no
268: * <code>TileCodecDescriptor</code> registered against the
269: * given <code>formatName</code>.
270: */
271: public static Iterator getIterator(OperationRegistry registry,
272: String formatName) {
273:
274: registry = (registry != null) ? registry : JAI
275: .getDefaultInstance().getOperationRegistry();
276:
277: return registry.getFactoryIterator(MODE_NAME, formatName);
278: }
279:
280: /**
281: * Returns the the most preferred <code>TileDecoderFactory</code>
282: * object registered against the given format name. This
283: * method will return the first <code>TileDecoderFactory</code> that
284: * would be encountered by the <code>Iterator</code> returned by the
285: * <code>getIterator()</code> method.
286: *
287: * @param registry The <code>OperationRegistry</code> to use.
288: * If this is <code>null</code>, then <code>
289: * JAI.getDefaultInstance().getOperationRegistry()</code>
290: * will be used.
291: * @param formatName The format name as a <code>String</code>
292: *
293: * @return a registered <code>TileDecoderFactory</code> object
294: *
295: * @throws IllegalArgumentException if formatName is <code>null</code>.
296: * @throws IllegalArgumentException if there is no
297: * <code>TileCodecDescriptor</code> registered against
298: * the <code>formatName</code>
299: */
300: public static TileDecoderFactory get(OperationRegistry registry,
301: String formatName) {
302:
303: registry = (registry != null) ? registry : JAI
304: .getDefaultInstance().getOperationRegistry();
305:
306: return (TileDecoderFactory) registry.getFactory(MODE_NAME,
307: formatName);
308: }
309:
310: /**
311: * Creates a <code>TileDecoder</code> for the specified format that is
312: * capable of handling the supplied arguments.
313: *
314: * <p> The preferences set amongst the <code>TileDecoderFactory</code>
315: * objects registered with the <code>OperationRegistry</code> are used
316: * to select the most prefered <code>TileDecoderFactory</code> whose
317: * <code>createDecoder()</code> method returns a non-null value.
318: *
319: * <p> In order to do the decoding correctly, the caller should
320: * retrieve the <code>TileCodecDescriptor</code> associated with the
321: * returned <code>TileDecoder</code> from the
322: * <code>OperationRegistry</code> and use it's
323: * <code>includesLocationInfo()</code> method's return value to decide
324: * which of the two versions of the <code>decode()</code> method on the
325: * returned <code>TileDecoder</code> should be used.
326: *
327: * <p>Since this class is a simple type-safe wrapper around
328: * <code>OperationRegistry</code>'s type-unsafe methods, no additional
329: * argument validation is performed in this method. Thus errors/exceptions
330: * may occur if incorrect values are provided for the input arguments.
331: *
332: * <p>Exceptions thrown by the <code>TileDecoderFactory</code>s used to
333: * create the <code>TileDecoder</code> will be caught by this method
334: * and will not be propagated.
335: *
336: * @param registry The <code>OperationRegistry</code> to use to create
337: * the <code>TileDecoder</code>. If
338: * this is <code>null</code>, then <code>
339: * JAI.getDefaultInstance().getOperationRegistry()</code>
340: * will be used.
341: * @param formatName The format for which the <code>TileDecoder</code> is
342: * to be created.
343: * @param input The <code>InputStream</code> to read encoded data from.
344: * @param paramList The object containing the tile decoding parameters.
345: *
346: * @throws IllegalArgumentException if formatName is null.
347: * @throws IllegalArgumentException if there is no
348: * <code>TileCodecDescriptor</code> registered against the
349: * given <code>formatName</code>.
350: */
351: public static TileDecoder create(OperationRegistry registry,
352: String formatName, InputStream input,
353: TileCodecParameterList paramList) {
354:
355: registry = (registry != null) ? registry : JAI
356: .getDefaultInstance().getOperationRegistry();
357:
358: Object args[] = { input, paramList };
359:
360: return (TileDecoder) registry.invokeFactory(MODE_NAME,
361: formatName, args);
362: }
363:
364: // Decode methods
365:
366: /**
367: * Decodes the data from the specified <code>InputStream</code>
368: * using the given formatName and <code>TileCodecParameterList</code>.
369: * The <code>TileDecoder</code> which performs the decoding is the
370: * one created from the most prefered <code>TileDecoderFactory</code>
371: * whose <code>create</code> method returns a non-null result.
372: *
373: * <p> An <code>IllegalArgumentException</code> will be thrown if
374: * the specified format's <code>TileCodecDescriptor</code>'s
375: * <code>includesLocationInfo()</code> method returns false, as no
376: * location information is provided in this method.
377: *
378: * <p> If the specified <code>TileCodecParameterList</code> is null, the
379: * default <code>TileCodecParameterList</code> retrieved by the specific
380: * <code>TileDecoder.getDefaultParameters</code>() method for the
381: * "tileDecoder" registry mode will be used.
382: *
383: * <p> For the specified format, if the associated
384: * <code>TileCodecDescriptor</code>'s <code>includesSampleModelInfo()</code>
385: * method returns false, and either the specified
386: * <code>TileCodecParameterList</code> is null or if it doesn't contain
387: * a non-value for the "sampleModel" parameter, an
388: * <code>IllegalArgumentException</code> will be thrown.
389: *
390: * <p> If there are no <code>TileDecoder</code> objects that can decode
391: * the specified <code>InputStream</code> according to the decoding
392: * parameters supplied, null will be returned from this method.
393: *
394: * <p> If multiple tiles are to be decoded from the same
395: * <code>InputStream</code> in the same format using the same
396: * <code>TileCodecParameterList</code>, it is advisable to create a
397: * <code>TileDecoder</code> object and use the <code>decode()</code> method
398: * on this decoder for each tile, thus creating and using only a single
399: * <code>TileDecoder</code> object. The <code>decode()</code>
400: * method on <code>TileDecoderRegistry</code> creates a new
401: * <code>TileDecoder</code> object each time it is called.
402: *
403: * <p>Since this class is a simple type-safe wrapper around
404: * <code>OperationRegistry</code>'s type-unsafe methods, no additional
405: * argument validation is performed in this method. Thus errors/exceptions
406: * may occur if incorrect values are provided for the input arguments.
407: *
408: * <p>Exceptions thrown by the <code>TileDecoderFactory</code>s used to
409: * create the <code>TileDecoder</code> will be caught by this method
410: * and will not be propagated.
411: *
412: * @param registry The <code>OperationRegistry</code> to use to create
413: * the <code>TileDecoder</code>. If
414: * this is <code>null</code>, then <code>
415: * JAI.getDefaultInstance().getOperationRegistry()</code>
416: * will be used.
417: * @param formatName The format name associated with the decoder.
418: * @param input The <code>InputStream</code> containing the data
419: * to be decoded.
420: * @param param The <code>TileCodecParameterList</code> to be used.
421: *
422: * @throws IllegalArgumentException if formatName is null.
423: * @throws IOException if an I/O error occurs while reading from the
424: * associated InputStream.
425: * @throws IllegalArgumentException if there is no
426: * <code>TileCodecDescriptor</code> registered against the
427: * given <code>formatName</code>.
428: *
429: * @return The associated <code>TileDecoder</code>, or <code>null</code>.
430: */
431: public static Raster decode(OperationRegistry registry,
432: String formatName, InputStream input,
433: TileCodecParameterList param) throws IOException {
434:
435: TileDecoder decoder = create(registry, formatName, input, param);
436:
437: if (decoder == null) {
438: return null;
439: }
440:
441: return decoder.decode();
442: }
443:
444: /**
445: * Decodes the data from the specified <code>InputStream</code>
446: * using the given formatName and <code>TileCodecParameterList</code>.
447: * The <code>TileDecoder</code> which performs the decoding is the
448: * one created from the most prefered <code>TileDecoderFactory</code>
449: * whose <code>create</code> method returns a non-null result. If
450: * there are no <code>TileDecoder</code> objects that can decode
451: * the specified <code>InputStream</code> according to the decoding
452: * parameters supplied, null will be returned from this method.
453: *
454: * <p> If the specified <code>TileCodecParameterList</code> is null, the
455: * default <code>TileCodecParameterList</code> retrieved by the specific
456: * <code>TileDecoder.getDefaultParameters()</code> method will be used.
457: *
458: * <p> If the specified location is null, and the associated
459: * <code>TileCodecDescriptor</code>'s <code>includesLocationInfo()</code>
460: * method returns false, <code>IllegalArgumentException</code> will be
461: * thrown.
462: *
463: * <p> For the specified format, if the associated
464: * <code>TileCodecDescriptor</code>'s <code>includesSampleModelInfo()</code>
465: * method returns false, and if the specified
466: * <code>TileCodecParameterList</code> is null or if it doesn't contain
467: * a non-value for the "sampleModel" parameter, an
468: * <code>IllegalArgumentException</code> will be thrown.
469: *
470: * <p> If multiple tiles are to be decoded from the same
471: * <code>InputStream</code> in the same format using the same
472: * <code>TileCodecParameterList</code>, it is advisable to create a
473: * <code>TileDecoder</code> object and use the <code>decode()</code> method
474: * on this decoder for each tile, thus creating and using only a single
475: * <code>TileDecoder</code> object. The <code>decode()</code>
476: * method on <code>TileDecoderRegistry</code> creates a new
477: * <code>TileDecoder</code> object each time it is called.
478: *
479: * <p>Since this class is a simple type-safe wrapper around
480: * <code>OperationRegistry</code>'s type-unsafe methods, no additional
481: * argument validation is performed in this method. Thus errors/exceptions
482: * may occur if incorrect values are provided for the input arguments.
483: *
484: * <p>Exceptions thrown by the <code>TileDecoderFactory</code>s used to
485: * create the <code>TileDecoder</code> will be caught by this method
486: * and will not be propagated.
487: *
488: * @param registry The <code>OperationRegistry</code> to use to create
489: * the <code>TileDecoder</code>. If
490: * this is <code>null</code>, then <code>
491: * JAI.getDefaultInstance().getOperationRegistry()</code>
492: * will be used.
493: * @param formatName The format name associated with the decoder.
494: * @param input The <code>InputStream</code> containing the data to
495: * be decoded.
496: * @param param The <code>TileCodecParameterList</code> to be used.
497: * @param location The <code>Point</code> specifying the upper left
498: * corner of the <code>Raster</code>.
499: *
500: * @throws IllegalArgumentException if formatName is null.
501: * @throws IOException if an inout/output error occurs while reading from
502: * the associated InputStream or during decoding.
503: * @throws IllegalArgumentException if there is no
504: * <code>TileCodecDescriptor</code> registered against the
505: * given <code>formatName</code>.
506:
507: * @return The associated <code>TileDecoder</code>, or <code>null</code>.
508: */
509: public static Raster decode(OperationRegistry registry,
510: String formatName, InputStream input,
511: TileCodecParameterList param, Point location)
512: throws IOException {
513:
514: TileDecoder decoder = create(registry, formatName, input, param);
515:
516: if (decoder == null) {
517: return null;
518: }
519:
520: return decoder.decode(location);
521: }
522: }
|