1 /*
   2  * Copyright (c) 2000, 2014, 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 = extraMetadataFormatNames.clone();
 195             this.extraMetadataFormatClassNames = extraMetadataFormatClassNames.clone();
 196         } else {
 197             if (extraMetadataFormatClassNames != null) {
 198                 throw new IllegalArgumentException
 199                     ("extraMetadataFormatNames == null && extraMetadataFormatClassNames != null!");
 200             }
 201         }
 202     }
 203 
 204     /**
 205      * Returns <code>true</code> if the standard metadata format is
 206      * supported by <code>getMetadataFormat</code>,
 207      * <code>getAsTree</code>, <code>setFromTree</code>, and
 208      * <code>mergeTree</code>.
 209      *
 210      * <p> The default implementation returns the value of the
 211      * <code>standardFormatSupported</code> instance variable.
 212      *
 213      * @return <code>true</code> if the standard metadata format
 214      * is supported.
 215      *
 216      * @see #getAsTree
 217      * @see #setFromTree
 218      * @see #mergeTree
 219      * @see #getMetadataFormat
 220      */
 221     public boolean isStandardMetadataFormatSupported() {
 222         return standardFormatSupported;
 223     }
 224 
 225     /**
 226      * Returns <code>true</code> if this object does not support the
 227      * <code>mergeTree</code>, <code>setFromTree</code>, and
 228      * <code>reset</code> methods.
 229      *
 230      * @return true if this <code>IIOMetadata</code> object cannot be
 231      * modified.
 232      */
 233     public abstract boolean isReadOnly();
 234 
 235     /**
 236      * Returns the name of the "native" metadata format for this
 237      * plug-in, which typically allows for lossless encoding and
 238      * transmission of the metadata stored in the format handled by
 239      * this plug-in.  If no such format is supported,
 240      * <code>null</code>will be returned.
 241      *
 242      * <p> The structure and contents of the "native" metadata format
 243      * are defined by the plug-in that created this
 244      * <code>IIOMetadata</code> object.  Plug-ins for simple formats
 245      * will usually create a dummy node for the root, and then a
 246      * series of child nodes representing individual tags, chunks, or
 247      * keyword/value pairs.  A plug-in may choose whether or not to
 248      * document its native format.
 249      *
 250      * <p> The default implementation returns the value of the
 251      * <code>nativeMetadataFormatName</code> instance variable.
 252      *
 253      * @return the name of the native format, or <code>null</code>.
 254      *
 255      * @see #getExtraMetadataFormatNames
 256      * @see #getMetadataFormatNames
 257      */
 258     public String getNativeMetadataFormatName() {
 259         return nativeMetadataFormatName;
 260     }
 261 
 262     /**
 263      * Returns an array of <code>String</code>s containing the names
 264      * of additional metadata formats, other than the native and standard
 265      * formats, recognized by this plug-in's
 266      * <code>getAsTree</code>, <code>setFromTree</code>, and
 267      * <code>mergeTree</code> methods.  If there are no such additional
 268      * formats, <code>null</code> is returned.
 269      *
 270      * <p> The default implementation returns a clone of the
 271      * <code>extraMetadataFormatNames</code> instance variable.
 272      *
 273      * @return an array of <code>String</code>s with length at least
 274      * 1, or <code>null</code>.
 275      *
 276      * @see #getAsTree
 277      * @see #setFromTree
 278      * @see #mergeTree
 279      * @see #getNativeMetadataFormatName
 280      * @see #getMetadataFormatNames
 281      */
 282     public String[] getExtraMetadataFormatNames() {
 283         if (extraMetadataFormatNames == null) {
 284             return null;
 285         }
 286         return extraMetadataFormatNames.clone();
 287     }
 288 
 289     /**
 290      * Returns an array of <code>String</code>s containing the names
 291      * of all metadata formats, including the native and standard
 292      * formats, recognized by this plug-in's <code>getAsTree</code>,
 293      * <code>setFromTree</code>, and <code>mergeTree</code> methods.
 294      * If there are no such formats, <code>null</code> is returned.
 295      *
 296      * <p> The default implementation calls
 297      * <code>getNativeMetadataFormatName</code>,
 298      * <code>isStandardMetadataFormatSupported</code>, and
 299      * <code>getExtraMetadataFormatNames</code> and returns the
 300      * combined results.
 301      *
 302      * @return an array of <code>String</code>s.
 303      *
 304      * @see #getNativeMetadataFormatName
 305      * @see #isStandardMetadataFormatSupported
 306      * @see #getExtraMetadataFormatNames
 307      */
 308     public String[] getMetadataFormatNames() {
 309         String nativeName = getNativeMetadataFormatName();
 310         String standardName = isStandardMetadataFormatSupported() ?
 311             IIOMetadataFormatImpl.standardMetadataFormatName : null;
 312         String[] extraNames = getExtraMetadataFormatNames();
 313 
 314         int numFormats = 0;
 315         if (nativeName != null) {
 316             ++numFormats;
 317         }
 318         if (standardName != null) {
 319             ++numFormats;
 320         }
 321         if (extraNames != null) {
 322             numFormats += extraNames.length;
 323         }
 324         if (numFormats == 0) {
 325             return null;
 326         }
 327 
 328         String[] formats = new String[numFormats];
 329         int index = 0;
 330         if (nativeName != null) {
 331             formats[index++] = nativeName;
 332         }
 333         if (standardName != null) {
 334             formats[index++] = standardName;
 335         }
 336         if (extraNames != null) {
 337             for (int i = 0; i < extraNames.length; i++) {
 338                 formats[index++] = extraNames[i];
 339             }
 340         }
 341 
 342         return formats;
 343     }
 344 
 345     /**
 346      * Returns an <code>IIOMetadataFormat</code> object describing the
 347      * given metadata format, or <code>null</code> if no description
 348      * is available.  The supplied name must be one of those returned
 349      * by <code>getMetadataFormatNames</code> (<i>i.e.</i>, either the
 350      * native format name, the standard format name, or one of those
 351      * returned by <code>getExtraMetadataFormatNames</code>).
 352      *
 353      * <p> The default implementation checks the name against the
 354      * global standard metadata format name, and returns that format
 355      * if it is supported.  Otherwise, it checks against the native
 356      * format names followed by any additional format names.  If a
 357      * match is found, it retrieves the name of the
 358      * <code>IIOMetadataFormat</code> class from
 359      * <code>nativeMetadataFormatClassName</code> or
 360      * <code>extraMetadataFormatClassNames</code> as appropriate, and
 361      * constructs an instance of that class using its
 362      * <code>getInstance</code> method.
 363      *
 364      * @param formatName the desired metadata format.
 365      *
 366      * @return an <code>IIOMetadataFormat</code> object.
 367      *
 368      * @exception IllegalArgumentException if <code>formatName</code>
 369      * is <code>null</code> or is not one of the names recognized by
 370      * the plug-in.
 371      * @exception IllegalStateException if the class corresponding to
 372      * the format name cannot be loaded.
 373      */
 374     public IIOMetadataFormat getMetadataFormat(String formatName) {
 375         if (formatName == null) {
 376             throw new IllegalArgumentException("formatName == null!");
 377         }
 378         if (standardFormatSupported
 379             && formatName.equals
 380                 (IIOMetadataFormatImpl.standardMetadataFormatName)) {
 381             return IIOMetadataFormatImpl.getStandardFormatInstance();
 382         }
 383         String formatClassName = null;
 384         if (formatName.equals(nativeMetadataFormatName)) {
 385             formatClassName = nativeMetadataFormatClassName;
 386         } else if (extraMetadataFormatNames != null) {
 387             for (int i = 0; i < extraMetadataFormatNames.length; i++) {
 388                 if (formatName.equals(extraMetadataFormatNames[i])) {
 389                     formatClassName = extraMetadataFormatClassNames[i];
 390                     break;  // out of for
 391                 }
 392             }
 393         }
 394         if (formatClassName == null) {
 395             throw new IllegalArgumentException("Unsupported format name");
 396         }
 397         try {
 398             Class<?> cls = null;
 399             final Object o = this;
 400 
 401             // firstly we try to use classloader used for loading
 402             // the IIOMetadata implemantation for this plugin.
 403             ClassLoader loader =
 404                 java.security.AccessController.doPrivileged(
 405                     new java.security.PrivilegedAction<ClassLoader>() {
 406                             public ClassLoader run() {
 407                                 return o.getClass().getClassLoader();
 408                             }
 409                         });
 410 
 411             try {
 412                 cls = Class.forName(formatClassName, true,
 413                                     loader);
 414             } catch (ClassNotFoundException e) {
 415                 // we failed to load IIOMetadataFormat class by
 416                 // using IIOMetadata classloader.Next try is to
 417                 // use thread context classloader.
 418                 loader =
 419                     java.security.AccessController.doPrivileged(
 420                         new java.security.PrivilegedAction<ClassLoader>() {
 421                                 public ClassLoader run() {
 422                                     return Thread.currentThread().getContextClassLoader();
 423                                 }
 424                         });
 425                 try {
 426                     cls = Class.forName(formatClassName, true,
 427                                         loader);
 428                 } catch (ClassNotFoundException e1) {
 429                     // finally we try to use system classloader in case
 430                     // if we failed to load IIOMetadataFormat implementation
 431                     // class above.
 432                     cls = Class.forName(formatClassName, true,
 433                                         ClassLoader.getSystemClassLoader());
 434                 }
 435             }
 436 
 437             Method meth = cls.getMethod("getInstance");
 438             return (IIOMetadataFormat) meth.invoke(null);
 439         } catch (Exception e) {
 440             RuntimeException ex =
 441                 new IllegalStateException ("Can't obtain format");
 442             ex.initCause(e);
 443             throw ex;
 444         }
 445 
 446     }
 447 
 448     /**
 449      * Returns an XML DOM <code>Node</code> object that represents the
 450      * root of a tree of metadata contained within this object
 451      * according to the conventions defined by a given metadata
 452      * format.
 453      *
 454      * <p> The names of the available metadata formats may be queried
 455      * using the <code>getMetadataFormatNames</code> method.
 456      *
 457      * @param formatName the desired metadata format.
 458      *
 459      * @return an XML DOM <code>Node</code> object forming the
 460      * root of a tree.
 461      *
 462      * @exception IllegalArgumentException if <code>formatName</code>
 463      * is <code>null</code> or is not one of the names returned by
 464      * <code>getMetadataFormatNames</code>.
 465      *
 466      * @see #getMetadataFormatNames
 467      * @see #setFromTree
 468      * @see #mergeTree
 469      */
 470     public abstract Node getAsTree(String formatName);
 471 
 472     /**
 473      * Alters the internal state of this <code>IIOMetadata</code>
 474      * object from a tree of XML DOM <code>Node</code>s whose syntax
 475      * is defined by the given metadata format.  The previous state is
 476      * altered only as necessary to accommodate the nodes that are
 477      * present in the given tree.  If the tree structure or contents
 478      * are invalid, an <code>IIOInvalidTreeException</code> will be
 479      * thrown.
 480      *
 481      * <p> As the semantics of how a tree or subtree may be merged with
 482      * another tree are completely format-specific, plug-in authors may
 483      * implement this method in whatever manner is most appropriate for
 484      * the format, including simply replacing all existing state with the
 485      * contents of the given tree.
 486      *
 487      * @param formatName the desired metadata format.
 488      * @param root an XML DOM <code>Node</code> object forming the
 489      * root of a tree.
 490      *
 491      * @exception IllegalStateException if this object is read-only.
 492      * @exception IllegalArgumentException if <code>formatName</code>
 493      * is <code>null</code> or is not one of the names returned by
 494      * <code>getMetadataFormatNames</code>.
 495      * @exception IllegalArgumentException if <code>root</code> is
 496      * <code>null</code>.
 497      * @exception IIOInvalidTreeException if the tree cannot be parsed
 498      * successfully using the rules of the given format.
 499      *
 500      * @see #getMetadataFormatNames
 501      * @see #getAsTree
 502      * @see #setFromTree
 503      */
 504     public abstract void mergeTree(String formatName, Node root)
 505         throws IIOInvalidTreeException;
 506 
 507     /**
 508      * Returns an <code>IIOMetadataNode</code> representing the chroma
 509      * information of the standard <code>javax_imageio_1.0</code>
 510      * metadata format, or <code>null</code> if no such information is
 511      * available.  This method is intended to be called by the utility
 512      * routine <code>getStandardTree</code>.
 513      *
 514      * <p> The default implementation returns <code>null</code>.
 515      *
 516      * <p> Subclasses should override this method to produce an
 517      * appropriate subtree if they wish to support the standard
 518      * metadata format.
 519      *
 520      * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
 521      *
 522      * @see #getStandardTree
 523      */
 524     protected IIOMetadataNode getStandardChromaNode() {
 525         return null;
 526     }
 527 
 528     /**
 529      * Returns an <code>IIOMetadataNode</code> representing the
 530      * compression information of the standard
 531      * <code>javax_imageio_1.0</code> metadata format, or
 532      * <code>null</code> if no such information is available.  This
 533      * method is intended to be called by the utility routine
 534      * <code>getStandardTree</code>.
 535      *
 536      * <p> The default implementation returns <code>null</code>.
 537      *
 538      * <p> Subclasses should override this method to produce an
 539      * appropriate subtree if they wish to support the standard
 540      * metadata format.
 541      *
 542      * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
 543      *
 544      * @see #getStandardTree
 545      */
 546     protected IIOMetadataNode getStandardCompressionNode() {
 547         return null;
 548     }
 549 
 550     /**
 551      * Returns an <code>IIOMetadataNode</code> representing the data
 552      * format information of the standard
 553      * <code>javax_imageio_1.0</code> metadata format, or
 554      * <code>null</code> if no such information is available.  This
 555      * method is intended to be called by the utility routine
 556      * <code>getStandardTree</code>.
 557      *
 558      * <p> The default implementation returns <code>null</code>.
 559      *
 560      * <p> Subclasses should override this method to produce an
 561      * appropriate subtree if they wish to support the standard
 562      * metadata format.
 563      *
 564      * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
 565      *
 566      * @see #getStandardTree
 567      */
 568     protected IIOMetadataNode getStandardDataNode() {
 569         return null;
 570     }
 571 
 572     /**
 573      * Returns an <code>IIOMetadataNode</code> representing the
 574      * dimension information of the standard
 575      * <code>javax_imageio_1.0</code> metadata format, or
 576      * <code>null</code> if no such information is available.  This
 577      * method is intended to be called by the utility routine
 578      * <code>getStandardTree</code>.
 579      *
 580      * <p> The default implementation returns <code>null</code>.
 581      *
 582      * <p> Subclasses should override this method to produce an
 583      * appropriate subtree if they wish to support the standard
 584      * metadata format.
 585      *
 586      * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
 587      *
 588      * @see #getStandardTree
 589      */
 590     protected IIOMetadataNode getStandardDimensionNode() {
 591         return null;
 592     }
 593 
 594     /**
 595      * Returns an <code>IIOMetadataNode</code> representing the document
 596      * information of the standard <code>javax_imageio_1.0</code>
 597      * metadata format, or <code>null</code> if no such information is
 598      * available.  This method is intended to be called by the utility
 599      * routine <code>getStandardTree</code>.
 600      *
 601      * <p> The default implementation returns <code>null</code>.
 602      *
 603      * <p> Subclasses should override this method to produce an
 604      * appropriate subtree if they wish to support the standard
 605      * metadata format.
 606      *
 607      * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
 608      *
 609      * @see #getStandardTree
 610      */
 611     protected IIOMetadataNode getStandardDocumentNode() {
 612         return null;
 613     }
 614 
 615     /**
 616      * Returns an <code>IIOMetadataNode</code> representing the textual
 617      * information of the standard <code>javax_imageio_1.0</code>
 618      * metadata format, or <code>null</code> if no such information is
 619      * available.  This method is intended to be called by the utility
 620      * routine <code>getStandardTree</code>.
 621      *
 622      * <p> The default implementation returns <code>null</code>.
 623      *
 624      * <p> Subclasses should override this method to produce an
 625      * appropriate subtree if they wish to support the standard
 626      * metadata format.
 627      *
 628      * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
 629      *
 630      * @see #getStandardTree
 631      */
 632     protected IIOMetadataNode getStandardTextNode() {
 633         return null;
 634     }
 635 
 636     /**
 637      * Returns an <code>IIOMetadataNode</code> representing the tiling
 638      * information of the standard <code>javax_imageio_1.0</code>
 639      * metadata format, or <code>null</code> if no such information is
 640      * available.  This method is intended to be called by the utility
 641      * routine <code>getStandardTree</code>.
 642      *
 643      * <p> The default implementation returns <code>null</code>.
 644      *
 645      * <p> Subclasses should override this method to produce an
 646      * appropriate subtree if they wish to support the standard
 647      * metadata format.
 648      *
 649      * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
 650      *
 651      * @see #getStandardTree
 652      */
 653     protected IIOMetadataNode getStandardTileNode() {
 654         return null;
 655     }
 656 
 657     /**
 658      * Returns an <code>IIOMetadataNode</code> representing the
 659      * transparency information of the standard
 660      * <code>javax_imageio_1.0</code> metadata format, or
 661      * <code>null</code> if no such information is available.  This
 662      * method is intended to be called by the utility routine
 663      * <code>getStandardTree</code>.
 664      *
 665      * <p> The default implementation returns <code>null</code>.
 666      *
 667      * <p> Subclasses should override this method to produce an
 668      * appropriate subtree if they wish to support the standard
 669      * metadata format.
 670      *
 671      * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
 672      */
 673     protected IIOMetadataNode getStandardTransparencyNode() {
 674         return null;
 675     }
 676 
 677     /**
 678      * Appends a new node to an existing node, if the new node is
 679      * non-<code>null</code>.
 680      */
 681     private void append(IIOMetadataNode root, IIOMetadataNode node) {
 682         if (node != null) {
 683             root.appendChild(node);
 684         }
 685     }
 686 
 687     /**
 688      * A utility method to return a tree of
 689      * <code>IIOMetadataNode</code>s representing the metadata
 690      * contained within this object according to the conventions of
 691      * the standard <code>javax_imageio_1.0</code> metadata format.
 692      *
 693      * <p> This method calls the various <code>getStandard*Node</code>
 694      * methods to supply each of the subtrees rooted at the children
 695      * of the root node.  If any of those methods returns
 696      * <code>null</code>, the corresponding subtree will be omitted.
 697      * If all of them return <code>null</code>, a tree consisting of a
 698      * single root node will be returned.
 699      *
 700      * @return an <code>IIOMetadataNode</code> representing the root
 701      * of a metadata tree in the <code>javax_imageio_1.0</code>
 702      * format.
 703      *
 704      * @see #getStandardChromaNode
 705      * @see #getStandardCompressionNode
 706      * @see #getStandardDataNode
 707      * @see #getStandardDimensionNode
 708      * @see #getStandardDocumentNode
 709      * @see #getStandardTextNode
 710      * @see #getStandardTileNode
 711      * @see #getStandardTransparencyNode
 712      */
 713     protected final IIOMetadataNode getStandardTree() {
 714         IIOMetadataNode root = new IIOMetadataNode
 715                 (IIOMetadataFormatImpl.standardMetadataFormatName);
 716         append(root, getStandardChromaNode());
 717         append(root, getStandardCompressionNode());
 718         append(root, getStandardDataNode());
 719         append(root, getStandardDimensionNode());
 720         append(root, getStandardDocumentNode());
 721         append(root, getStandardTextNode());
 722         append(root, getStandardTileNode());
 723         append(root, getStandardTransparencyNode());
 724         return root;
 725     }
 726 
 727     /**
 728      * Sets the internal state of this <code>IIOMetadata</code> object
 729      * from a tree of XML DOM <code>Node</code>s whose syntax is
 730      * defined by the given metadata format.  The previous state is
 731      * discarded.  If the tree's structure or contents are invalid, an
 732      * <code>IIOInvalidTreeException</code> will be thrown.
 733      *
 734      * <p> The default implementation calls <code>reset</code>
 735      * followed by <code>mergeTree(formatName, root)</code>.
 736      *
 737      * @param formatName the desired metadata format.
 738      * @param root an XML DOM <code>Node</code> object forming the
 739      * root of a tree.
 740      *
 741      * @exception IllegalStateException if this object is read-only.
 742      * @exception IllegalArgumentException if <code>formatName</code>
 743      * is <code>null</code> or is not one of the names returned by
 744      * <code>getMetadataFormatNames</code>.
 745      * @exception IllegalArgumentException if <code>root</code> is
 746      * <code>null</code>.
 747      * @exception IIOInvalidTreeException if the tree cannot be parsed
 748      * successfully using the rules of the given format.
 749      *
 750      * @see #getMetadataFormatNames
 751      * @see #getAsTree
 752      * @see #mergeTree
 753      */
 754     public void setFromTree(String formatName, Node root)
 755         throws IIOInvalidTreeException {
 756         reset();
 757         mergeTree(formatName, root);
 758     }
 759 
 760     /**
 761      * Resets all the data stored in this object to default values,
 762      * usually to the state this object was in immediately after
 763      * construction, though the precise semantics are plug-in specific.
 764      * Note that there are many possible default values, depending on
 765      * how the object was created.
 766      *
 767      * @exception IllegalStateException if this object is read-only.
 768      *
 769      * @see javax.imageio.ImageReader#getStreamMetadata
 770      * @see javax.imageio.ImageReader#getImageMetadata
 771      * @see javax.imageio.ImageWriter#getDefaultStreamMetadata
 772      * @see javax.imageio.ImageWriter#getDefaultImageMetadata
 773      */
 774     public abstract void reset();
 775 
 776     /**
 777      * Sets the <code>IIOMetadataController</code> to be used
 778      * to provide settings for this <code>IIOMetadata</code>
 779      * object when the <code>activateController</code> method
 780      * is called, overriding any default controller.  If the
 781      * argument is <code>null</code>, no controller will be
 782      * used, including any default.  To restore the default, use
 783      * <code>setController(getDefaultController())</code>.
 784      *
 785      * <p> The default implementation sets the <code>controller</code>
 786      * instance variable to the supplied value.
 787      *
 788      * @param controller An appropriate
 789      * <code>IIOMetadataController</code>, or <code>null</code>.
 790      *
 791      * @see IIOMetadataController
 792      * @see #getController
 793      * @see #getDefaultController
 794      * @see #hasController
 795      * @see #activateController()
 796      */
 797     public void setController(IIOMetadataController controller) {
 798         this.controller = controller;
 799     }
 800 
 801     /**
 802      * Returns whatever <code>IIOMetadataController</code> is currently
 803      * installed.  This could be the default if there is one,
 804      * <code>null</code>, or the argument of the most recent call
 805      * to <code>setController</code>.
 806      *
 807      * <p> The default implementation returns the value of the
 808      * <code>controller</code> instance variable.
 809      *
 810      * @return the currently installed
 811      * <code>IIOMetadataController</code>, or <code>null</code>.
 812      *
 813      * @see IIOMetadataController
 814      * @see #setController
 815      * @see #getDefaultController
 816      * @see #hasController
 817      * @see #activateController()
 818      */
 819     public IIOMetadataController getController() {
 820         return controller;
 821     }
 822 
 823     /**
 824      * Returns the default <code>IIOMetadataController</code>, if there
 825      * is one, regardless of the currently installed controller.  If
 826      * there is no default controller, returns <code>null</code>.
 827      *
 828      * <p> The default implementation returns the value of the
 829      * <code>defaultController</code> instance variable.
 830      *
 831      * @return the default <code>IIOMetadataController</code>, or
 832      * <code>null</code>.
 833      *
 834      * @see IIOMetadataController
 835      * @see #setController(IIOMetadataController)
 836      * @see #getController
 837      * @see #hasController
 838      * @see #activateController()
 839      */
 840     public IIOMetadataController getDefaultController() {
 841         return defaultController;
 842     }
 843 
 844     /**
 845      * Returns <code>true</code> if there is a controller installed
 846      * for this <code>IIOMetadata</code> object.
 847      *
 848      * <p> The default implementation returns <code>true</code> if the
 849      * <code>getController</code> method returns a
 850      * non-<code>null</code> value.
 851      *
 852      * @return <code>true</code> if a controller is installed.
 853      *
 854      * @see IIOMetadataController
 855      * @see #setController(IIOMetadataController)
 856      * @see #getController
 857      * @see #getDefaultController
 858      * @see #activateController()
 859      */
 860     public boolean hasController() {
 861         return (getController() != null);
 862     }
 863 
 864     /**
 865      * Activates the installed <code>IIOMetadataController</code> for
 866      * this <code>IIOMetadata</code> object and returns the resulting
 867      * value.  When this method returns <code>true</code>, all values for this
 868      * <code>IIOMetadata</code> object will be ready for the next write
 869      * operation.  If <code>false</code> is
 870      * returned, no settings in this object will have been disturbed
 871      * (<i>i.e.</i>, the user canceled the operation).
 872      *
 873      * <p> Ordinarily, the controller will be a GUI providing a user
 874      * interface for a subclass of <code>IIOMetadata</code> for a
 875      * particular plug-in.  Controllers need not be GUIs, however.
 876      *
 877      * <p> The default implementation calls <code>getController</code>
 878      * and the calls <code>activate</code> on the returned object if
 879      * <code>hasController</code> returns <code>true</code>.
 880      *
 881      * @return <code>true</code> if the controller completed normally.
 882      *
 883      * @exception IllegalStateException if there is no controller
 884      * currently installed.
 885      *
 886      * @see IIOMetadataController
 887      * @see #setController(IIOMetadataController)
 888      * @see #getController
 889      * @see #getDefaultController
 890      * @see #hasController
 891      */
 892     public boolean activateController() {
 893         if (!hasController()) {
 894             throw new IllegalStateException("hasController() == false!");
 895         }
 896         return getController().activate(this);
 897     }
 898 }