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