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