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