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     // If updating this method also see the same in ImageReaderWriterSpi.java
 418     private Class<?> getMetadataFormatClass(String formatClassName) {
 419         Module thisModule = IIOMetadata.class.getModule();
 420         Module targetModule = this.getClass().getModule();
 421         Class<?> c = null;
 422         try {
 423             ClassLoader cl = this.getClass().getClassLoader();
 424             c = Class.forName(formatClassName, false, cl);
 425             if (!IIOMetadataFormat.class.isAssignableFrom(c)) {
 426                 return null;
 427             }
 428         } catch (ClassNotFoundException e) {
 429         }
 430         if (thisModule.equals(targetModule) || c == null) {
 431             return c;
 432         }
 433         if (targetModule.isNamed()) {
 434             int i = formatClassName.lastIndexOf(".");
 435             String pn = i > 0 ? formatClassName.substring(0, i) : "";
 436             if (!targetModule.isExported(pn, thisModule)) {
 437                 throw new IllegalStateException("Class " + formatClassName +
 438                    " in named module must be exported to java.desktop module.");
 439             }
 440         }
 441         return c;
 442     }
 443 
 444     /**
 445      * Returns an XML DOM {@code Node} object that represents the
 446      * root of a tree of metadata contained within this object
 447      * according to the conventions defined by a given metadata
 448      * format.
 449      *
 450      * <p> The names of the available metadata formats may be queried
 451      * using the {@code getMetadataFormatNames} method.
 452      *
 453      * @param formatName the desired metadata format.
 454      *
 455      * @return an XML DOM {@code Node} object forming the
 456      * root of a tree.
 457      *
 458      * @exception IllegalArgumentException if {@code formatName}
 459      * is {@code null} or is not one of the names returned by
 460      * {@code getMetadataFormatNames}.
 461      *
 462      * @see #getMetadataFormatNames
 463      * @see #setFromTree
 464      * @see #mergeTree
 465      */
 466     public abstract Node getAsTree(String formatName);
 467 
 468     /**
 469      * Alters the internal state of this {@code IIOMetadata}
 470      * object from a tree of XML DOM {@code Node}s whose syntax
 471      * is defined by the given metadata format.  The previous state is
 472      * altered only as necessary to accommodate the nodes that are
 473      * present in the given tree.  If the tree structure or contents
 474      * are invalid, an {@code IIOInvalidTreeException} will be
 475      * thrown.
 476      *
 477      * <p> As the semantics of how a tree or subtree may be merged with
 478      * another tree are completely format-specific, plug-in authors may
 479      * implement this method in whatever manner is most appropriate for
 480      * the format, including simply replacing all existing state with the
 481      * contents of the given tree.
 482      *
 483      * @param formatName the desired metadata format.
 484      * @param root an XML DOM {@code Node} object forming the
 485      * root of a tree.
 486      *
 487      * @exception IllegalStateException if this object is read-only.
 488      * @exception IllegalArgumentException if {@code formatName}
 489      * is {@code null} or is not one of the names returned by
 490      * {@code getMetadataFormatNames}.
 491      * @exception IllegalArgumentException if {@code root} is
 492      * {@code null}.
 493      * @exception IIOInvalidTreeException if the tree cannot be parsed
 494      * successfully using the rules of the given format.
 495      *
 496      * @see #getMetadataFormatNames
 497      * @see #getAsTree
 498      * @see #setFromTree
 499      */
 500     public abstract void mergeTree(String formatName, Node root)
 501         throws IIOInvalidTreeException;
 502 
 503     /**
 504      * Returns an {@code IIOMetadataNode} representing the chroma
 505      * information of the standard {@code javax_imageio_1.0}
 506      * metadata format, or {@code null} if no such information is
 507      * available.  This method is intended to be called by the utility
 508      * routine {@code getStandardTree}.
 509      *
 510      * <p> The default implementation returns {@code null}.
 511      *
 512      * <p> Subclasses should override this method to produce an
 513      * appropriate subtree if they wish to support the standard
 514      * metadata format.
 515      *
 516      * @return an {@code IIOMetadataNode}, or {@code null}.
 517      *
 518      * @see #getStandardTree
 519      */
 520     protected IIOMetadataNode getStandardChromaNode() {
 521         return null;
 522     }
 523 
 524     /**
 525      * Returns an {@code IIOMetadataNode} representing the
 526      * compression information of the standard
 527      * {@code javax_imageio_1.0} metadata format, or
 528      * {@code null} if no such information is available.  This
 529      * method is intended to be called by the utility routine
 530      * {@code getStandardTree}.
 531      *
 532      * <p> The default implementation returns {@code null}.
 533      *
 534      * <p> Subclasses should override this method to produce an
 535      * appropriate subtree if they wish to support the standard
 536      * metadata format.
 537      *
 538      * @return an {@code IIOMetadataNode}, or {@code null}.
 539      *
 540      * @see #getStandardTree
 541      */
 542     protected IIOMetadataNode getStandardCompressionNode() {
 543         return null;
 544     }
 545 
 546     /**
 547      * Returns an {@code IIOMetadataNode} representing the data
 548      * format information of the standard
 549      * {@code javax_imageio_1.0} metadata format, or
 550      * {@code null} if no such information is available.  This
 551      * method is intended to be called by the utility routine
 552      * {@code getStandardTree}.
 553      *
 554      * <p> The default implementation returns {@code null}.
 555      *
 556      * <p> Subclasses should override this method to produce an
 557      * appropriate subtree if they wish to support the standard
 558      * metadata format.
 559      *
 560      * @return an {@code IIOMetadataNode}, or {@code null}.
 561      *
 562      * @see #getStandardTree
 563      */
 564     protected IIOMetadataNode getStandardDataNode() {
 565         return null;
 566     }
 567 
 568     /**
 569      * Returns an {@code IIOMetadataNode} representing the
 570      * dimension information of the standard
 571      * {@code javax_imageio_1.0} metadata format, or
 572      * {@code null} if no such information is available.  This
 573      * method is intended to be called by the utility routine
 574      * {@code getStandardTree}.
 575      *
 576      * <p> The default implementation returns {@code null}.
 577      *
 578      * <p> Subclasses should override this method to produce an
 579      * appropriate subtree if they wish to support the standard
 580      * metadata format.
 581      *
 582      * @return an {@code IIOMetadataNode}, or {@code null}.
 583      *
 584      * @see #getStandardTree
 585      */
 586     protected IIOMetadataNode getStandardDimensionNode() {
 587         return null;
 588     }
 589 
 590     /**
 591      * Returns an {@code IIOMetadataNode} representing the document
 592      * information of the standard {@code javax_imageio_1.0}
 593      * metadata format, or {@code null} if no such information is
 594      * available.  This method is intended to be called by the utility
 595      * routine {@code getStandardTree}.
 596      *
 597      * <p> The default implementation returns {@code null}.
 598      *
 599      * <p> Subclasses should override this method to produce an
 600      * appropriate subtree if they wish to support the standard
 601      * metadata format.
 602      *
 603      * @return an {@code IIOMetadataNode}, or {@code null}.
 604      *
 605      * @see #getStandardTree
 606      */
 607     protected IIOMetadataNode getStandardDocumentNode() {
 608         return null;
 609     }
 610 
 611     /**
 612      * Returns an {@code IIOMetadataNode} representing the textual
 613      * information of the standard {@code javax_imageio_1.0}
 614      * metadata format, or {@code null} if no such information is
 615      * available.  This method is intended to be called by the utility
 616      * routine {@code getStandardTree}.
 617      *
 618      * <p> The default implementation returns {@code null}.
 619      *
 620      * <p> Subclasses should override this method to produce an
 621      * appropriate subtree if they wish to support the standard
 622      * metadata format.
 623      *
 624      * @return an {@code IIOMetadataNode}, or {@code null}.
 625      *
 626      * @see #getStandardTree
 627      */
 628     protected IIOMetadataNode getStandardTextNode() {
 629         return null;
 630     }
 631 
 632     /**
 633      * Returns an {@code IIOMetadataNode} representing the tiling
 634      * information of the standard {@code javax_imageio_1.0}
 635      * metadata format, or {@code null} if no such information is
 636      * available.  This method is intended to be called by the utility
 637      * routine {@code getStandardTree}.
 638      *
 639      * <p> The default implementation returns {@code null}.
 640      *
 641      * <p> Subclasses should override this method to produce an
 642      * appropriate subtree if they wish to support the standard
 643      * metadata format.
 644      *
 645      * @return an {@code IIOMetadataNode}, or {@code null}.
 646      *
 647      * @see #getStandardTree
 648      */
 649     protected IIOMetadataNode getStandardTileNode() {
 650         return null;
 651     }
 652 
 653     /**
 654      * Returns an {@code IIOMetadataNode} representing the
 655      * transparency information of the standard
 656      * {@code javax_imageio_1.0} metadata format, or
 657      * {@code null} if no such information is available.  This
 658      * method is intended to be called by the utility routine
 659      * {@code getStandardTree}.
 660      *
 661      * <p> The default implementation returns {@code null}.
 662      *
 663      * <p> Subclasses should override this method to produce an
 664      * appropriate subtree if they wish to support the standard
 665      * metadata format.
 666      *
 667      * @return an {@code IIOMetadataNode}, or {@code null}.
 668      */
 669     protected IIOMetadataNode getStandardTransparencyNode() {
 670         return null;
 671     }
 672 
 673     /**
 674      * Appends a new node to an existing node, if the new node is
 675      * non-{@code null}.
 676      */
 677     private void append(IIOMetadataNode root, IIOMetadataNode node) {
 678         if (node != null) {
 679             root.appendChild(node);
 680         }
 681     }
 682 
 683     /**
 684      * A utility method to return a tree of
 685      * {@code IIOMetadataNode}s representing the metadata
 686      * contained within this object according to the conventions of
 687      * the standard {@code javax_imageio_1.0} metadata format.
 688      *
 689      * <p> This method calls the various {@code getStandard*Node}
 690      * methods to supply each of the subtrees rooted at the children
 691      * of the root node.  If any of those methods returns
 692      * {@code null}, the corresponding subtree will be omitted.
 693      * If all of them return {@code null}, a tree consisting of a
 694      * single root node will be returned.
 695      *
 696      * @return an {@code IIOMetadataNode} representing the root
 697      * of a metadata tree in the {@code javax_imageio_1.0}
 698      * format.
 699      *
 700      * @see #getStandardChromaNode
 701      * @see #getStandardCompressionNode
 702      * @see #getStandardDataNode
 703      * @see #getStandardDimensionNode
 704      * @see #getStandardDocumentNode
 705      * @see #getStandardTextNode
 706      * @see #getStandardTileNode
 707      * @see #getStandardTransparencyNode
 708      */
 709     protected final IIOMetadataNode getStandardTree() {
 710         IIOMetadataNode root = new IIOMetadataNode
 711                 (IIOMetadataFormatImpl.standardMetadataFormatName);
 712         append(root, getStandardChromaNode());
 713         append(root, getStandardCompressionNode());
 714         append(root, getStandardDataNode());
 715         append(root, getStandardDimensionNode());
 716         append(root, getStandardDocumentNode());
 717         append(root, getStandardTextNode());
 718         append(root, getStandardTileNode());
 719         append(root, getStandardTransparencyNode());
 720         return root;
 721     }
 722 
 723     /**
 724      * Sets the internal state of this {@code IIOMetadata} object
 725      * from a tree of XML DOM {@code Node}s whose syntax is
 726      * defined by the given metadata format.  The previous state is
 727      * discarded.  If the tree's structure or contents are invalid, an
 728      * {@code IIOInvalidTreeException} will be thrown.
 729      *
 730      * <p> The default implementation calls {@code reset}
 731      * followed by {@code mergeTree(formatName, root)}.
 732      *
 733      * @param formatName the desired metadata format.
 734      * @param root an XML DOM {@code Node} object forming the
 735      * root of a tree.
 736      *
 737      * @exception IllegalStateException if this object is read-only.
 738      * @exception IllegalArgumentException if {@code formatName}
 739      * is {@code null} or is not one of the names returned by
 740      * {@code getMetadataFormatNames}.
 741      * @exception IllegalArgumentException if {@code root} is
 742      * {@code null}.
 743      * @exception IIOInvalidTreeException if the tree cannot be parsed
 744      * successfully using the rules of the given format.
 745      *
 746      * @see #getMetadataFormatNames
 747      * @see #getAsTree
 748      * @see #mergeTree
 749      */
 750     public void setFromTree(String formatName, Node root)
 751         throws IIOInvalidTreeException {
 752         reset();
 753         mergeTree(formatName, root);
 754     }
 755 
 756     /**
 757      * Resets all the data stored in this object to default values,
 758      * usually to the state this object was in immediately after
 759      * construction, though the precise semantics are plug-in specific.
 760      * Note that there are many possible default values, depending on
 761      * how the object was created.
 762      *
 763      * @exception IllegalStateException if this object is read-only.
 764      *
 765      * @see javax.imageio.ImageReader#getStreamMetadata
 766      * @see javax.imageio.ImageReader#getImageMetadata
 767      * @see javax.imageio.ImageWriter#getDefaultStreamMetadata
 768      * @see javax.imageio.ImageWriter#getDefaultImageMetadata
 769      */
 770     public abstract void reset();
 771 
 772     /**
 773      * Sets the {@code IIOMetadataController} to be used
 774      * to provide settings for this {@code IIOMetadata}
 775      * object when the {@code activateController} method
 776      * is called, overriding any default controller.  If the
 777      * argument is {@code null}, no controller will be
 778      * used, including any default.  To restore the default, use
 779      * {@code setController(getDefaultController())}.
 780      *
 781      * <p> The default implementation sets the {@code controller}
 782      * instance variable to the supplied value.
 783      *
 784      * @param controller An appropriate
 785      * {@code IIOMetadataController}, or {@code null}.
 786      *
 787      * @see IIOMetadataController
 788      * @see #getController
 789      * @see #getDefaultController
 790      * @see #hasController
 791      * @see #activateController()
 792      */
 793     public void setController(IIOMetadataController controller) {
 794         this.controller = controller;
 795     }
 796 
 797     /**
 798      * Returns whatever {@code IIOMetadataController} is currently
 799      * installed.  This could be the default if there is one,
 800      * {@code null}, or the argument of the most recent call
 801      * to {@code setController}.
 802      *
 803      * <p> The default implementation returns the value of the
 804      * {@code controller} instance variable.
 805      *
 806      * @return the currently installed
 807      * {@code IIOMetadataController}, or {@code null}.
 808      *
 809      * @see IIOMetadataController
 810      * @see #setController
 811      * @see #getDefaultController
 812      * @see #hasController
 813      * @see #activateController()
 814      */
 815     public IIOMetadataController getController() {
 816         return controller;
 817     }
 818 
 819     /**
 820      * Returns the default {@code IIOMetadataController}, if there
 821      * is one, regardless of the currently installed controller.  If
 822      * there is no default controller, returns {@code null}.
 823      *
 824      * <p> The default implementation returns the value of the
 825      * {@code defaultController} instance variable.
 826      *
 827      * @return the default {@code IIOMetadataController}, or
 828      * {@code null}.
 829      *
 830      * @see IIOMetadataController
 831      * @see #setController(IIOMetadataController)
 832      * @see #getController
 833      * @see #hasController
 834      * @see #activateController()
 835      */
 836     public IIOMetadataController getDefaultController() {
 837         return defaultController;
 838     }
 839 
 840     /**
 841      * Returns {@code true} if there is a controller installed
 842      * for this {@code IIOMetadata} object.
 843      *
 844      * <p> The default implementation returns {@code true} if the
 845      * {@code getController} method returns a
 846      * non-{@code null} value.
 847      *
 848      * @return {@code true} if a controller is installed.
 849      *
 850      * @see IIOMetadataController
 851      * @see #setController(IIOMetadataController)
 852      * @see #getController
 853      * @see #getDefaultController
 854      * @see #activateController()
 855      */
 856     public boolean hasController() {
 857         return (getController() != null);
 858     }
 859 
 860     /**
 861      * Activates the installed {@code IIOMetadataController} for
 862      * this {@code IIOMetadata} object and returns the resulting
 863      * value.  When this method returns {@code true}, all values for this
 864      * {@code IIOMetadata} object will be ready for the next write
 865      * operation.  If {@code false} is
 866      * returned, no settings in this object will have been disturbed
 867      * (<i>i.e.</i>, the user canceled the operation).
 868      *
 869      * <p> Ordinarily, the controller will be a GUI providing a user
 870      * interface for a subclass of {@code IIOMetadata} for a
 871      * particular plug-in.  Controllers need not be GUIs, however.
 872      *
 873      * <p> The default implementation calls {@code getController}
 874      * and the calls {@code activate} on the returned object if
 875      * {@code hasController} returns {@code true}.
 876      *
 877      * @return {@code true} if the controller completed normally.
 878      *
 879      * @exception IllegalStateException if there is no controller
 880      * currently installed.
 881      *
 882      * @see IIOMetadataController
 883      * @see #setController(IIOMetadataController)
 884      * @see #getController
 885      * @see #getDefaultController
 886      * @see #hasController
 887      */
 888     public boolean activateController() {
 889         if (!hasController()) {
 890             throw new IllegalStateException("hasController() == false!");
 891         }
 892         return getController().activate(this);
 893     }
 894 }