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