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