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