001 /*
002 * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.imageio.metadata;
027
028 import org.w3c.dom.Node;
029 import java.lang.reflect.Method;
030
031 /**
032 * An abstract class to be extended by objects that represent metadata
033 * (non-image data) associated with images and streams. Plug-ins
034 * represent metadata using opaque, plug-in specific objects. These
035 * objects, however, provide the ability to access their internal
036 * information as a tree of <code>IIOMetadataNode</code> objects that
037 * support the XML DOM interfaces as well as additional interfaces for
038 * storing non-textual data and retrieving information about legal
039 * data values. The format of such trees is plug-in dependent, but
040 * plug-ins may choose to support a plug-in neutral format described
041 * below. A single plug-in may support multiple metadata formats,
042 * whose names maybe determined by calling
043 * <code>getMetadataFormatNames</code>. The plug-in may also support
044 * a single special format, referred to as the "native" format, which
045 * is designed to encode its metadata losslessly. This format will
046 * typically be designed specifically to work with a specific file
047 * format, so that images may be loaded and saved in the same format
048 * with no loss of metadata, but may be less useful for transfering
049 * metadata between an <code>ImageReader</code> and an
050 * <code>ImageWriter</code> for different image formats. To convert
051 * between two native formats as losslessly as the image file formats
052 * will allow, an <code>ImageTranscoder</code> object must be used.
053 *
054 * @see javax.imageio.ImageReader#getImageMetadata
055 * @see javax.imageio.ImageReader#getStreamMetadata
056 * @see javax.imageio.ImageReader#readAll
057 * @see javax.imageio.ImageWriter#getDefaultStreamMetadata
058 * @see javax.imageio.ImageWriter#getDefaultImageMetadata
059 * @see javax.imageio.ImageWriter#write
060 * @see javax.imageio.ImageWriter#convertImageMetadata
061 * @see javax.imageio.ImageWriter#convertStreamMetadata
062 * @see javax.imageio.IIOImage
063 * @see javax.imageio.ImageTranscoder
064 *
065 * @version 0.5
066 */
067 public abstract class IIOMetadata {
068
069 /**
070 * A boolean indicating whether the concrete subclass supports the
071 * standard metadata format, set via the constructor.
072 */
073 protected boolean standardFormatSupported;
074
075 /**
076 * The name of the native metadata format for this object,
077 * initialized to <code>null</code> and set via the constructor.
078 */
079 protected String nativeMetadataFormatName = null;
080
081 /**
082 * The name of the class implementing <code>IIOMetadataFormat</code>
083 * and representing the native metadata format, initialized to
084 * <code>null</code> and set via the constructor.
085 */
086 protected String nativeMetadataFormatClassName = null;
087
088 /**
089 * An array of names of formats, other than the standard and
090 * native formats, that are supported by this plug-in,
091 * initialized to <code>null</code> and set via the constructor.
092 */
093 protected String[] extraMetadataFormatNames = null;
094
095 /**
096 * An array of names of classes implementing <code>IIOMetadataFormat</code>
097 * and representing the metadata formats, other than the standard and
098 * native formats, that are supported by this plug-in,
099 * initialized to <code>null</code> and set via the constructor.
100 */
101 protected String[] extraMetadataFormatClassNames = null;
102
103 /**
104 * An <code>IIOMetadataController</code> that is suggested for use
105 * as the controller for this <code>IIOMetadata</code> object. It
106 * may be retrieved via <code>getDefaultController</code>. To
107 * install the default controller, call
108 * <code>setController(getDefaultController())</code>. This
109 * instance variable should be set by subclasses that choose to
110 * provide their own default controller, usually a GUI, for
111 * setting parameters.
112 *
113 * @see IIOMetadataController
114 * @see #getDefaultController
115 */
116 protected IIOMetadataController defaultController = null;
117
118 /**
119 * The <code>IIOMetadataController</code> that will be
120 * used to provide settings for this <code>IIOMetadata</code>
121 * object when the <code>activateController</code> method
122 * is called. This value overrides any default controller,
123 * even when <code>null</code>.
124 *
125 * @see IIOMetadataController
126 * @see #setController(IIOMetadataController)
127 * @see #hasController()
128 * @see #activateController()
129 */
130 protected IIOMetadataController controller = null;
131
132 /**
133 * Constructs an empty <code>IIOMetadata</code> object. The
134 * subclass is responsible for suppying values for all protected
135 * instance variables that will allow any non-overridden default
136 * implemtations of methods to satisfy their contracts. For example,
137 * <code>extraMetadataFormatNames</code> should not have length 0.
138 */
139 protected IIOMetadata() {
140 }
141
142 /**
143 * Constructs an <code>IIOMetadata</code> object with the given
144 * format names and format class names, as well as a boolean
145 * indicating whether the standard format is supported.
146 *
147 * <p> This constructor does not attempt to check the class names
148 * for validity. Invalid class names may cause exceptions in
149 * subsequent calls to <code>getMetadataFormat</code>.
150 *
151 * @param standardMetadataFormatSupported <code>true</code> if
152 * this object can return or accept a DOM tree using the standard
153 * metadata format.
154 * @param nativeMetadataFormatName the name of the native metadata
155 * format, as a <code>String</code>, or <code>null</code> if there
156 * is no native format.
157 * @param nativeMetadataFormatClassName the name of the class of
158 * the native metadata format, or <code>null</code> if there is
159 * no native format.
160 * @param extraMetadataFormatNames an array of <code>String</code>s
161 * indicating additional formats supported by this object, or
162 * <code>null</code> if there are none.
163 * @param extraMetadataFormatClassNames an array of <code>String</code>s
164 * indicating the class names of any additional formats supported by
165 * this object, or <code>null</code> if there are none.
166 *
167 * @exception IllegalArgumentException if
168 * <code>extraMetadataFormatNames</code> has length 0.
169 * @exception IllegalArgumentException if
170 * <code>extraMetadataFormatNames</code> and
171 * <code>extraMetadataFormatClassNames</code> are neither both
172 * <code>null</code>, nor of the same length.
173 */
174 protected IIOMetadata(boolean standardMetadataFormatSupported,
175 String nativeMetadataFormatName,
176 String nativeMetadataFormatClassName,
177 String[] extraMetadataFormatNames,
178 String[] extraMetadataFormatClassNames) {
179 this .standardFormatSupported = standardMetadataFormatSupported;
180 this .nativeMetadataFormatName = nativeMetadataFormatName;
181 this .nativeMetadataFormatClassName = nativeMetadataFormatClassName;
182 if (extraMetadataFormatNames != null) {
183 if (extraMetadataFormatNames.length == 0) {
184 throw new IllegalArgumentException(
185 "extraMetadataFormatNames.length == 0!");
186 }
187 if (extraMetadataFormatClassNames == null) {
188 throw new IllegalArgumentException(
189 "extraMetadataFormatNames != null && extraMetadataFormatClassNames == null!");
190 }
191 if (extraMetadataFormatClassNames.length != extraMetadataFormatNames.length) {
192 throw new IllegalArgumentException(
193 "extraMetadataFormatClassNames.length != extraMetadataFormatNames.length!");
194 }
195 this .extraMetadataFormatNames = (String[]) extraMetadataFormatNames
196 .clone();
197 this .extraMetadataFormatClassNames = (String[]) extraMetadataFormatClassNames
198 .clone();
199 } else {
200 if (extraMetadataFormatClassNames != null) {
201 throw new IllegalArgumentException(
202 "extraMetadataFormatNames == null && extraMetadataFormatClassNames != null!");
203 }
204 }
205 }
206
207 /**
208 * Returns <code>true</code> if the standard metadata format is
209 * supported by <code>getMetadataFormat</code>,
210 * <code>getAsTree</code>, <code>setFromTree</code>, and
211 * <code>mergeTree</code>.
212 *
213 * <p> The default implementation returns the value of the
214 * <code>standardFormatSupported</code> instance variable.
215 *
216 * @return <code>true</code> if the standard metadata format
217 * is supported.
218 *
219 * @see #getAsTree
220 * @see #setFromTree
221 * @see #mergeTree
222 * @see #getMetadataFormat
223 */
224 public boolean isStandardMetadataFormatSupported() {
225 return standardFormatSupported;
226 }
227
228 /**
229 * Returns <code>true</code> if this object does not support the
230 * <code>mergeTree</code>, <code>setFromTree</code>, and
231 * <code>reset</code> methods.
232 *
233 * @return true if this <code>IIOMetadata</code> object cannot be
234 * modified.
235 */
236 public abstract boolean isReadOnly();
237
238 /**
239 * Returns the name of the "native" metadata format for this
240 * plug-in, which typically allows for lossless encoding and
241 * transmission of the metadata stored in the format handled by
242 * this plug-in. If no such format is supported,
243 * <code>null</code>will be returned.
244 *
245 * <p> The structure and contents of the "native" metadata format
246 * are defined by the plug-in that created this
247 * <code>IIOMetadata</code> object. Plug-ins for simple formats
248 * will usually create a dummy node for the root, and then a
249 * series of child nodes representing individual tags, chunks, or
250 * keyword/value pairs. A plug-in may choose whether or not to
251 * document its native format.
252 *
253 * <p> The default implementation returns the value of the
254 * <code>nativeMetadataFormatName</code> instance variable.
255 *
256 * @return the name of the native format, or <code>null</code>.
257 *
258 * @see #getExtraMetadataFormatNames
259 * @see #getMetadataFormatNames
260 */
261 public String getNativeMetadataFormatName() {
262 return nativeMetadataFormatName;
263 }
264
265 /**
266 * Returns an array of <code>String</code>s containing the names
267 * of additional metadata formats, other than the native and standard
268 * formats, recognized by this plug-in's
269 * <code>getAsTree</code>, <code>setFromTree</code>, and
270 * <code>mergeTree</code> methods. If there are no such additional
271 * formats, <code>null</code> is returned.
272 *
273 * <p> The default implementation returns a clone of the
274 * <code>extraMetadataFormatNames</code> instance variable.
275 *
276 * @return an array of <code>String</code>s with length at least
277 * 1, or <code>null</code>.
278 *
279 * @see #getAsTree
280 * @see #setFromTree
281 * @see #mergeTree
282 * @see #getNativeMetadataFormatName
283 * @see #getMetadataFormatNames
284 */
285 public String[] getExtraMetadataFormatNames() {
286 if (extraMetadataFormatNames == null) {
287 return null;
288 }
289 return (String[]) extraMetadataFormatNames.clone();
290 }
291
292 /**
293 * Returns an array of <code>String</code>s containing the names
294 * of all metadata formats, including the native and standard
295 * formats, recognized by this plug-in's <code>getAsTree</code>,
296 * <code>setFromTree</code>, and <code>mergeTree</code> methods.
297 * If there are no such formats, <code>null</code> is returned.
298 *
299 * <p> The default implementation calls
300 * <code>getNativeMetadataFormatName</code>,
301 * <code>isStandardMetadataFormatSupported</code>, and
302 * <code>getExtraMetadataFormatNames</code> and returns the
303 * combined results.
304 *
305 * @return an array of <code>String</code>s.
306 *
307 * @see #getNativeMetadataFormatName
308 * @see #isStandardMetadataFormatSupported
309 * @see #getExtraMetadataFormatNames
310 */
311 public String[] getMetadataFormatNames() {
312 String nativeName = getNativeMetadataFormatName();
313 String standardName = isStandardMetadataFormatSupported() ? IIOMetadataFormatImpl.standardMetadataFormatName
314 : null;
315 String[] extraNames = getExtraMetadataFormatNames();
316
317 int numFormats = 0;
318 if (nativeName != null) {
319 ++numFormats;
320 }
321 if (standardName != null) {
322 ++numFormats;
323 }
324 if (extraNames != null) {
325 numFormats += extraNames.length;
326 }
327 if (numFormats == 0) {
328 return null;
329 }
330
331 String[] formats = new String[numFormats];
332 int index = 0;
333 if (nativeName != null) {
334 formats[index++] = nativeName;
335 }
336 if (standardName != null) {
337 formats[index++] = standardName;
338 }
339 if (extraNames != null) {
340 for (int i = 0; i < extraNames.length; i++) {
341 formats[index++] = extraNames[i];
342 }
343 }
344
345 return formats;
346 }
347
348 /**
349 * Returns an <code>IIOMetadataFormat</code> object describing the
350 * given metadata format, or <code>null</code> if no description
351 * is available. The supplied name must be one of those returned
352 * by <code>getMetadataFormatNames</code> (<i>i.e.</i>, either the
353 * native format name, the standard format name, or one of those
354 * returned by <code>getExtraMetadataFormatNames</code>).
355 *
356 * <p> The default implementation checks the name against the
357 * global standard metadata format name, and returns that format
358 * if it is supported. Otherwise, it checks against the native
359 * format names followed by any additional format names. If a
360 * match is found, it retrieves the name of the
361 * <code>IIOMetadataFormat</code> class from
362 * <code>nativeMetadataFormatClassName</code> or
363 * <code>extraMetadataFormatClassNames</code> as appropriate, and
364 * constructs an instance of that class using its
365 * <code>getInstance</code> method.
366 *
367 * @param formatName the desired metadata format.
368 *
369 * @return an <code>IIOMetadataFormat</code> object.
370 *
371 * @exception IllegalArgumentException if <code>formatName</code>
372 * is <code>null</code> or is not one of the names recognized by
373 * the plug-in.
374 * @exception IllegalStateException if the class corresponding to
375 * the format name cannot be loaded.
376 */
377 public IIOMetadataFormat getMetadataFormat(String formatName) {
378 if (formatName == null) {
379 throw new IllegalArgumentException("formatName == null!");
380 }
381 if (standardFormatSupported
382 && formatName
383 .equals(IIOMetadataFormatImpl.standardMetadataFormatName)) {
384 return IIOMetadataFormatImpl.getStandardFormatInstance();
385 }
386 String formatClassName = null;
387 if (formatName.equals(nativeMetadataFormatName)) {
388 formatClassName = nativeMetadataFormatClassName;
389 } else if (extraMetadataFormatNames != null) {
390 for (int i = 0; i < extraMetadataFormatNames.length; i++) {
391 if (formatName.equals(extraMetadataFormatNames[i])) {
392 formatClassName = extraMetadataFormatClassNames[i];
393 break; // out of for
394 }
395 }
396 }
397 if (formatClassName == null) {
398 throw new IllegalArgumentException(
399 "Unsupported format name");
400 }
401 try {
402 Class cls = null;
403 final Object o = this ;
404
405 // firstly we try to use classloader used for loading
406 // the IIOMetadata implemantation for this plugin.
407 ClassLoader loader = (ClassLoader) java.security.AccessController
408 .doPrivileged(new java.security.PrivilegedAction() {
409 public Object run() {
410 return o.getClass().getClassLoader();
411 }
412 });
413
414 try {
415 cls = Class.forName(formatClassName, true, loader);
416 } catch (ClassNotFoundException e) {
417 // we failed to load IIOMetadataFormat class by
418 // using IIOMetadata classloader.Next try is to
419 // use thread context classloader.
420 loader = (ClassLoader) java.security.AccessController
421 .doPrivileged(new java.security.PrivilegedAction() {
422 public Object run() {
423 return Thread.currentThread()
424 .getContextClassLoader();
425 }
426 });
427 try {
428 cls = Class.forName(formatClassName, true, loader);
429 } catch (ClassNotFoundException e1) {
430 // finally we try to use system classloader in case
431 // if we failed to load IIOMetadataFormat implementation
432 // class above.
433 cls = Class.forName(formatClassName, true,
434 ClassLoader.getSystemClassLoader());
435 }
436 }
437
438 Method meth = cls.getMethod("getInstance");
439 return (IIOMetadataFormat) meth.invoke(null);
440 } catch (Exception e) {
441 RuntimeException ex = new IllegalStateException(
442 "Can't obtain format");
443 ex.initCause(e);
444 throw ex;
445 }
446
447 }
448
449 /**
450 * Returns an XML DOM <code>Node</code> object that represents the
451 * root of a tree of metadata contained within this object
452 * according to the conventions defined by a given metadata
453 * format.
454 *
455 * <p> The names of the available metadata formats may be queried
456 * using the <code>getMetadataFormatNames</code> method.
457 *
458 * @param formatName the desired metadata format.
459 *
460 * @return an XML DOM <code>Node</code> object forming the
461 * root of a tree.
462 *
463 * @exception IllegalArgumentException if <code>formatName</code>
464 * is <code>null</code> or is not one of the names returned by
465 * <code>getMetadataFormatNames</code>.
466 *
467 * @see #getMetadataFormatNames
468 * @see #setFromTree
469 * @see #mergeTree
470 */
471 public abstract Node getAsTree(String formatName);
472
473 /**
474 * Alters the internal state of this <code>IIOMetadata</code>
475 * object from a tree of XML DOM <code>Node</code>s whose syntax
476 * is defined by the given metadata format. The previous state is
477 * altered only as necessary to accomodate the nodes that are
478 * present in the given tree. If the tree structure or contents
479 * are invalid, an <code>IIOInvalidTreeException</code> will be
480 * thrown.
481 *
482 * <p> As the semantics of how a tree or subtree may be merged with
483 * another tree are completely format-specific, plug-in authors may
484 * implement this method in whatever manner is most appropriate for
485 * the format, including simply replacing all existing state with the
486 * contents of the given tree.
487 *
488 * @param formatName the desired metadata format.
489 * @param root an XML DOM <code>Node</code> object forming the
490 * root of a tree.
491 *
492 * @exception IllegalStateException if this object is read-only.
493 * @exception IllegalArgumentException if <code>formatName</code>
494 * is <code>null</code> or is not one of the names returned by
495 * <code>getMetadataFormatNames</code>.
496 * @exception IllegalArgumentException if <code>root</code> is
497 * <code>null</code>.
498 * @exception IIOInvalidTreeException if the tree cannot be parsed
499 * successfully using the rules of the given format.
500 *
501 * @see #getMetadataFormatNames
502 * @see #getAsTree
503 * @see #setFromTree
504 */
505 public abstract void mergeTree(String formatName, Node root)
506 throws IIOInvalidTreeException;
507
508 /**
509 * Returns an <code>IIOMetadataNode</code> representing the chroma
510 * information of the standard <code>javax_imageio_1.0</code>
511 * metadata format, or <code>null</code> if no such information is
512 * available. This method is intended to be called by the utility
513 * routine <code>getStandardTree</code>.
514 *
515 * <p> The default implementation returns <code>null</code>.
516 *
517 * <p> Subclasses should override this method to produce an
518 * appropriate subtree if they wish to support the standard
519 * metadata format.
520 *
521 * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
522 *
523 * @see #getStandardTree
524 */
525 protected IIOMetadataNode getStandardChromaNode() {
526 return null;
527 }
528
529 /**
530 * Returns an <code>IIOMetadataNode</code> representing the
531 * compression information of the standard
532 * <code>javax_imageio_1.0</code> metadata format, or
533 * <code>null</code> if no such information is available. This
534 * method is intended to be called by the utility routine
535 * <code>getStandardTree</code>.
536 *
537 * <p> The default implementation returns <code>null</code>.
538 *
539 * <p> Subclasses should override this method to produce an
540 * appropriate subtree if they wish to support the standard
541 * metadata format.
542 *
543 * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
544 *
545 * @see #getStandardTree
546 */
547 protected IIOMetadataNode getStandardCompressionNode() {
548 return null;
549 }
550
551 /**
552 * Returns an <code>IIOMetadataNode</code> representing the data
553 * format information of the standard
554 * <code>javax_imageio_1.0</code> metadata format, or
555 * <code>null</code> if no such information is available. This
556 * method is intended to be called by the utility routine
557 * <code>getStandardTree</code>.
558 *
559 * <p> The default implementation returns <code>null</code>.
560 *
561 * <p> Subclasses should override this method to produce an
562 * appropriate subtree if they wish to support the standard
563 * metadata format.
564 *
565 * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
566 *
567 * @see #getStandardTree
568 */
569 protected IIOMetadataNode getStandardDataNode() {
570 return null;
571 }
572
573 /**
574 * Returns an <code>IIOMetadataNode</code> representing the
575 * dimension information of the standard
576 * <code>javax_imageio_1.0</code> metadata format, or
577 * <code>null</code> if no such information is available. This
578 * method is intended to be called by the utility routine
579 * <code>getStandardTree</code>.
580 *
581 * <p> The default implementation returns <code>null</code>.
582 *
583 * <p> Subclasses should override this method to produce an
584 * appropriate subtree if they wish to support the standard
585 * metadata format.
586 *
587 * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
588 *
589 * @see #getStandardTree
590 */
591 protected IIOMetadataNode getStandardDimensionNode() {
592 return null;
593 }
594
595 /**
596 * Returns an <code>IIOMetadataNode</code> representing the document
597 * information of the standard <code>javax_imageio_1.0</code>
598 * metadata format, or <code>null</code> if no such information is
599 * available. This method is intended to be called by the utility
600 * routine <code>getStandardTree</code>.
601 *
602 * <p> The default implementation returns <code>null</code>.
603 *
604 * <p> Subclasses should override this method to produce an
605 * appropriate subtree if they wish to support the standard
606 * metadata format.
607 *
608 * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
609 *
610 * @see #getStandardTree
611 */
612 protected IIOMetadataNode getStandardDocumentNode() {
613 return null;
614 }
615
616 /**
617 * Returns an <code>IIOMetadataNode</code> representing the textual
618 * information of the standard <code>javax_imageio_1.0</code>
619 * metadata format, or <code>null</code> if no such information is
620 * available. This method is intended to be called by the utility
621 * routine <code>getStandardTree</code>.
622 *
623 * <p> The default implementation returns <code>null</code>.
624 *
625 * <p> Subclasses should override this method to produce an
626 * appropriate subtree if they wish to support the standard
627 * metadata format.
628 *
629 * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
630 *
631 * @see #getStandardTree
632 */
633 protected IIOMetadataNode getStandardTextNode() {
634 return null;
635 }
636
637 /**
638 * Returns an <code>IIOMetadataNode</code> representing the tiling
639 * information of the standard <code>javax_imageio_1.0</code>
640 * metadata format, or <code>null</code> if no such information is
641 * available. This method is intended to be called by the utility
642 * routine <code>getStandardTree</code>.
643 *
644 * <p> The default implementation returns <code>null</code>.
645 *
646 * <p> Subclasses should override this method to produce an
647 * appropriate subtree if they wish to support the standard
648 * metadata format.
649 *
650 * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
651 *
652 * @see #getStandardTree
653 */
654 protected IIOMetadataNode getStandardTileNode() {
655 return null;
656 }
657
658 /**
659 * Returns an <code>IIOMetadataNode</code> representing the
660 * transparency information of the standard
661 * <code>javax_imageio_1.0</code> metadata format, or
662 * <code>null</code> if no such information is available. This
663 * method is intended to be called by the utility routine
664 * <code>getStandardTree</code>.
665 *
666 * <p> The default implementation returns <code>null</code>.
667 *
668 * <p> Subclasses should override this method to produce an
669 * appropriate subtree if they wish to support the standard
670 * metadata format.
671 *
672 * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
673 */
674 protected IIOMetadataNode getStandardTransparencyNode() {
675 return null;
676 }
677
678 /**
679 * Appends a new node to an existing node, if the new node is
680 * non-<code>null</code>.
681 */
682 private void append(IIOMetadataNode root, IIOMetadataNode node) {
683 if (node != null) {
684 root.appendChild(node);
685 }
686 }
687
688 /**
689 * A utility method to return a tree of
690 * <code>IIOMetadataNode</code>s representing the metadata
691 * contained within this object according to the conventions of
692 * the standard <code>javax_imageio_1.0</code> metadata format.
693 *
694 * <p> This method calls the various <code>getStandard*Node</code>
695 * methods to supply each of the subtrees rooted at the children
696 * of the root node. If any of those methods returns
697 * <code>null</code>, the corresponding subtree will be omitted.
698 * If all of them return <code>null</code>, a tree consisting of a
699 * single root node will be returned.
700 *
701 * @return an <code>IIOMetadataNode</code> representing the root
702 * of a metadata tree in the <code>javax_imageio_1.0</code>
703 * format.
704 *
705 * @see #getStandardChromaNode
706 * @see #getStandardCompressionNode
707 * @see #getStandardDataNode
708 * @see #getStandardDimensionNode
709 * @see #getStandardDocumentNode
710 * @see #getStandardTextNode
711 * @see #getStandardTileNode
712 * @see #getStandardTransparencyNode
713 */
714 protected final IIOMetadataNode getStandardTree() {
715 IIOMetadataNode root = new IIOMetadataNode(
716 IIOMetadataFormatImpl.standardMetadataFormatName);
717 append(root, getStandardChromaNode());
718 append(root, getStandardCompressionNode());
719 append(root, getStandardDataNode());
720 append(root, getStandardDimensionNode());
721 append(root, getStandardDocumentNode());
722 append(root, getStandardTextNode());
723 append(root, getStandardTileNode());
724 append(root, getStandardTransparencyNode());
725 return root;
726 }
727
728 /**
729 * Sets the internal state of this <code>IIOMetadata</code> object
730 * from a tree of XML DOM <code>Node</code>s whose syntax is
731 * defined by the given metadata format. The previous state is
732 * discarded. If the tree's structure or contents are invalid, an
733 * <code>IIOInvalidTreeException</code> will be thrown.
734 *
735 * <p> The default implementation calls <code>reset</code>
736 * followed by <code>mergeTree(formatName, root)</code>.
737 *
738 * @param formatName the desired metadata format.
739 * @param root an XML DOM <code>Node</code> object forming the
740 * root of a tree.
741 *
742 * @exception IllegalStateException if this object is read-only.
743 * @exception IllegalArgumentException if <code>formatName</code>
744 * is <code>null</code> or is not one of the names returned by
745 * <code>getMetadataFormatNames</code>.
746 * @exception IllegalArgumentException if <code>root</code> is
747 * <code>null</code>.
748 * @exception IIOInvalidTreeException if the tree cannot be parsed
749 * successfully using the rules of the given format.
750 *
751 * @see #getMetadataFormatNames
752 * @see #getAsTree
753 * @see #mergeTree
754 */
755 public void setFromTree(String formatName, Node root)
756 throws IIOInvalidTreeException {
757 reset();
758 mergeTree(formatName, root);
759 }
760
761 /**
762 * Resets all the data stored in this object to default values,
763 * usually to the state this object was in immediately after
764 * construction, though the precise semantics are plug-in specific.
765 * Note that there are many possible default values, depending on
766 * how the object was created.
767 *
768 * @exception IllegalStateException if this object is read-only.
769 *
770 * @see javax.imageio.ImageReader#getStreamMetadata
771 * @see javax.imageio.ImageReader#getImageMetadata
772 * @see javax.imageio.ImageWriter#getDefaultStreamMetadata
773 * @see javax.imageio.ImageWriter#getDefaultImageMetadata
774 */
775 public abstract void reset();
776
777 /**
778 * Sets the <code>IIOMetadataController</code> to be used
779 * to provide settings for this <code>IIOMetadata</code>
780 * object when the <code>activateController</code> method
781 * is called, overriding any default controller. If the
782 * argument is <code>null</code>, no controller will be
783 * used, including any default. To restore the default, use
784 * <code>setController(getDefaultController())</code>.
785 *
786 * <p> The default implementation sets the <code>controller</code>
787 * instance variable to the supplied value.
788 *
789 * @param controller An appropriate
790 * <code>IIOMetadataController</code>, or <code>null</code>.
791 *
792 * @see IIOMetadataController
793 * @see #getController
794 * @see #getDefaultController
795 * @see #hasController
796 * @see #activateController()
797 */
798 public void setController(IIOMetadataController controller) {
799 this .controller = controller;
800 }
801
802 /**
803 * Returns whatever <code>IIOMetadataController</code> is currently
804 * installed. This could be the default if there is one,
805 * <code>null</code>, or the argument of the most recent call
806 * to <code>setController</code>.
807 *
808 * <p> The default implementation returns the value of the
809 * <code>controller</code> instance variable.
810 *
811 * @return the currently installed
812 * <code>IIOMetadataController</code>, or <code>null</code>.
813 *
814 * @see IIOMetadataController
815 * @see #setController
816 * @see #getDefaultController
817 * @see #hasController
818 * @see #activateController()
819 */
820 public IIOMetadataController getController() {
821 return controller;
822 }
823
824 /**
825 * Returns the default <code>IIOMetadataController</code>, if there
826 * is one, regardless of the currently installed controller. If
827 * there is no default controller, returns <code>null</code>.
828 *
829 * <p> The default implementation returns the value of the
830 * <code>defaultController</code> instance variable.
831 *
832 * @return the default <code>IIOMetadataController</code>, or
833 * <code>null</code>.
834 *
835 * @see IIOMetadataController
836 * @see #setController(IIOMetadataController)
837 * @see #getController
838 * @see #hasController
839 * @see #activateController()
840 */
841 public IIOMetadataController getDefaultController() {
842 return defaultController;
843 }
844
845 /**
846 * Returns <code>true</code> if there is a controller installed
847 * for this <code>IIOMetadata</code> object.
848 *
849 * <p> The default implementation returns <code>true</code> if the
850 * <code>getController</code> method returns a
851 * non-<code>null</code> value.
852 *
853 * @return <code>true</code> if a controller is installed.
854 *
855 * @see IIOMetadataController
856 * @see #setController(IIOMetadataController)
857 * @see #getController
858 * @see #getDefaultController
859 * @see #activateController()
860 */
861 public boolean hasController() {
862 return (getController() != null);
863 }
864
865 /**
866 * Activates the installed <code>IIOMetadataController</code> for
867 * this <code>IIOMetadata</code> object and returns the resulting
868 * value. When this method returns <code>true</code>, all values for this
869 * <code>IIOMetadata</code> object will be ready for the next write
870 * operation. If <code>false</code> is
871 * returned, no settings in this object will have been disturbed
872 * (<i>i.e.</i>, the user canceled the operation).
873 *
874 * <p> Ordinarily, the controller will be a GUI providing a user
875 * interface for a subclass of <code>IIOMetadata</code> for a
876 * particular plug-in. Controllers need not be GUIs, however.
877 *
878 * <p> The default implementation calls <code>getController</code>
879 * and the calls <code>activate</code> on the returned object if
880 * <code>hasController</code> returns <code>true</code>.
881 *
882 * @return <code>true</code> if the controller completed normally.
883 *
884 * @exception IllegalStateException if there is no controller
885 * currently installed.
886 *
887 * @see IIOMetadataController
888 * @see #setController(IIOMetadataController)
889 * @see #getController
890 * @see #getDefaultController
891 * @see #hasController
892 */
893 public boolean activateController() {
894 if (!hasController()) {
895 throw new IllegalStateException("hasController() == false!");
896 }
897 return getController().activate(this);
898 }
899 }
|