1. /*
  2. * @(#)IIOMetadata.java 1.39 04/03/19
  3. *
  4. * Copyright 2004 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 = null;
  363. final Object o = this;
  364. // firstly we try to use classloader used for loading
  365. // the IIOMetadata implemantation for this plugin.
  366. ClassLoader loader = (ClassLoader)
  367. java.security.AccessController.doPrivileged(
  368. new java.security.PrivilegedAction() {
  369. public Object run() {
  370. return o.getClass().getClassLoader();
  371. }
  372. });
  373. try {
  374. cls = Class.forName(formatClassName, true,
  375. loader);
  376. } catch (ClassNotFoundException e) {
  377. // we failed to load IIOMetadataFormat class by
  378. // using IIOMetadata classloader.Next try is to
  379. // use thread context classloader.
  380. loader = (ClassLoader)
  381. java.security.AccessController.doPrivileged(
  382. new java.security.PrivilegedAction() {
  383. public Object run() {
  384. return Thread.currentThread().getContextClassLoader();
  385. }
  386. });
  387. try {
  388. cls = Class.forName(formatClassName, true,
  389. loader);
  390. } catch (ClassNotFoundException e1) {
  391. // finally we try to use system classloader in case
  392. // if we failed to load IIOMetadataFormat implementation
  393. // class above.
  394. cls = Class.forName(formatClassName, true,
  395. ClassLoader.getSystemClassLoader());
  396. }
  397. }
  398. Method meth = cls.getMethod("getInstance", null);
  399. return (IIOMetadataFormat) meth.invoke(null, null);
  400. } catch (Exception e) {
  401. RuntimeException ex =
  402. new IllegalStateException ("Can't obtain format");
  403. ex.initCause(e);
  404. throw ex;
  405. }
  406. }
  407. /**
  408. * Returns an XML DOM <code>Node</code> object that represents the
  409. * root of a tree of metadata contained within this object
  410. * according to the conventions defined by a given metadata
  411. * format.
  412. *
  413. * <p> The names of the available metadata formats may be queried
  414. * using the <code>getMetadataFormatNames</code> method.
  415. *
  416. * @param formatName the desired metadata format.
  417. *
  418. * @return an XML DOM <code>Node</code> object forming the
  419. * root of a tree.
  420. *
  421. * @exception IllegalArgumentException if <code>formatName</code>
  422. * is <code>null</code> or is not one of the names returned by
  423. * <code>getMetadataFormatNames</code>.
  424. *
  425. * @see #getMetadataFormatNames
  426. * @see #setFromTree
  427. * @see #mergeTree
  428. */
  429. public abstract Node getAsTree(String formatName);
  430. /**
  431. * Alters the internal state of this <code>IIOMetadata</code>
  432. * object from a tree of XML DOM <code>Node</code>s whose syntax
  433. * is defined by the given metadata format. The previous state is
  434. * altered only as necessary to accomodate the nodes that are
  435. * present in the given tree. If the tree structure or contents
  436. * are invalid, an <code>IIOInvalidTreeException</code> will be
  437. * thrown.
  438. *
  439. * <p> As the semantics of how a tree or subtree may be merged with
  440. * another tree are completely format-specific, plug-in authors may
  441. * implement this method in whatever manner is most appropriate for
  442. * the format, including simply replacing all existing state with the
  443. * contents of the given tree.
  444. *
  445. * @param formatName the desired metadata format.
  446. * @param root an XML DOM <code>Node</code> object forming the
  447. * root of a tree.
  448. *
  449. * @exception IllegalStateException if this object is read-only.
  450. * @exception IllegalArgumentException if <code>formatName</code>
  451. * is <code>null</code> or is not one of the names returned by
  452. * <code>getMetadataFormatNames</code>.
  453. * @exception IllegalArgumentException if <code>root</code> is
  454. * <code>null</code>.
  455. * @exception IIOInvalidTreeException if the tree cannot be parsed
  456. * successfully using the rules of the given format.
  457. *
  458. * @see #getMetadataFormatNames
  459. * @see #getAsTree
  460. * @see #setFromTree
  461. */
  462. public abstract void mergeTree(String formatName, Node root)
  463. throws IIOInvalidTreeException;
  464. /**
  465. * Returns an <code>IIOMetadataNode</code> representing the chroma
  466. * information of the standard <code>javax_imageio_1.0</code>
  467. * metadata format, or <code>null</code> if no such information is
  468. * available. This method is intended to be called by the utility
  469. * routine <code>getStandardTree</code>.
  470. *
  471. * <p> The default implementation returns <code>null</code>.
  472. *
  473. * <p> Subclasses should override this method to produce an
  474. * appropriate subtree if they wish to support the standard
  475. * metadata format.
  476. *
  477. * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
  478. *
  479. * @see #getStandardTree
  480. */
  481. protected IIOMetadataNode getStandardChromaNode() {
  482. return null;
  483. }
  484. /**
  485. * Returns an <code>IIOMetadataNode</code> representing the
  486. * compression information of the standard
  487. * <code>javax_imageio_1.0</code> metadata format, or
  488. * <code>null</code> if no such information is available. This
  489. * method is intended to be called by the utility routine
  490. * <code>getStandardTree</code>.
  491. *
  492. * <p> The default implementation returns <code>null</code>.
  493. *
  494. * <p> Subclasses should override this method to produce an
  495. * appropriate subtree if they wish to support the standard
  496. * metadata format.
  497. *
  498. * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
  499. *
  500. * @see #getStandardTree
  501. */
  502. protected IIOMetadataNode getStandardCompressionNode() {
  503. return null;
  504. }
  505. /**
  506. * Returns an <code>IIOMetadataNode</code> representing the data
  507. * format information of the standard
  508. * <code>javax_imageio_1.0</code> metadata format, or
  509. * <code>null</code> if no such information is available. This
  510. * method is intended to be called by the utility routine
  511. * <code>getStandardTree</code>.
  512. *
  513. * <p> The default implementation returns <code>null</code>.
  514. *
  515. * <p> Subclasses should override this method to produce an
  516. * appropriate subtree if they wish to support the standard
  517. * metadata format.
  518. *
  519. * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
  520. *
  521. * @see #getStandardTree
  522. */
  523. protected IIOMetadataNode getStandardDataNode() {
  524. return null;
  525. }
  526. /**
  527. * Returns an <code>IIOMetadataNode</code> representing the
  528. * dimension information of the standard
  529. * <code>javax_imageio_1.0</code> metadata format, or
  530. * <code>null</code> if no such information is available. This
  531. * method is intended to be called by the utility routine
  532. * <code>getStandardTree</code>.
  533. *
  534. * <p> The default implementation returns <code>null</code>.
  535. *
  536. * <p> Subclasses should override this method to produce an
  537. * appropriate subtree if they wish to support the standard
  538. * metadata format.
  539. *
  540. * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
  541. *
  542. * @see #getStandardTree
  543. */
  544. protected IIOMetadataNode getStandardDimensionNode() {
  545. return null;
  546. }
  547. /**
  548. * Returns an <code>IIOMetadataNode</code> representing the document
  549. * information of the standard <code>javax_imageio_1.0</code>
  550. * metadata format, or <code>null</code> if no such information is
  551. * available. This method is intended to be called by the utility
  552. * routine <code>getStandardTree</code>.
  553. *
  554. * <p> The default implementation returns <code>null</code>.
  555. *
  556. * <p> Subclasses should override this method to produce an
  557. * appropriate subtree if they wish to support the standard
  558. * metadata format.
  559. *
  560. * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
  561. *
  562. * @see #getStandardTree
  563. */
  564. protected IIOMetadataNode getStandardDocumentNode() {
  565. return null;
  566. }
  567. /**
  568. * Returns an <code>IIOMetadataNode</code> representing the textual
  569. * information of the standard <code>javax_imageio_1.0</code>
  570. * metadata format, or <code>null</code> if no such information is
  571. * available. This method is intended to be called by the utility
  572. * routine <code>getStandardTree</code>.
  573. *
  574. * <p> The default implementation returns <code>null</code>.
  575. *
  576. * <p> Subclasses should override this method to produce an
  577. * appropriate subtree if they wish to support the standard
  578. * metadata format.
  579. *
  580. * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
  581. *
  582. * @see #getStandardTree
  583. */
  584. protected IIOMetadataNode getStandardTextNode() {
  585. return null;
  586. }
  587. /**
  588. * Returns an <code>IIOMetadataNode</code> representing the tiling
  589. * information of the standard <code>javax_imageio_1.0</code>
  590. * metadata format, or <code>null</code> if no such information is
  591. * available. This method is intended to be called by the utility
  592. * routine <code>getStandardTree</code>.
  593. *
  594. * <p> The default implementation returns <code>null</code>.
  595. *
  596. * <p> Subclasses should override this method to produce an
  597. * appropriate subtree if they wish to support the standard
  598. * metadata format.
  599. *
  600. * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
  601. *
  602. * @see #getStandardTree
  603. */
  604. protected IIOMetadataNode getStandardTileNode() {
  605. return null;
  606. }
  607. /**
  608. * Returns an <code>IIOMetadataNode</code> representing the
  609. * transparency information of the standard
  610. * <code>javax_imageio_1.0</code> metadata format, or
  611. * <code>null</code> if no such information is available. This
  612. * method is intended to be called by the utility routine
  613. * <code>getStandardTree</code>.
  614. *
  615. * <p> The default implementation returns <code>null</code>.
  616. *
  617. * <p> Subclasses should override this method to produce an
  618. * appropriate subtree if they wish to support the standard
  619. * metadata format.
  620. *
  621. * @return an <code>IIOMetadataNode</code>, or <code>null</code>.
  622. */
  623. protected IIOMetadataNode getStandardTransparencyNode() {
  624. return null;
  625. }
  626. /**
  627. * Appends a new node to an existing node, if the new node is
  628. * non-<code>null</code>.
  629. */
  630. private void append(IIOMetadataNode root, IIOMetadataNode node) {
  631. if (node != null) {
  632. root.appendChild(node);
  633. }
  634. }
  635. /**
  636. * A utility method to return a tree of
  637. * <code>IIOMetadataNode</code>s representing the metadata
  638. * contained within this object according to the conventions of
  639. * the standard <code>javax_imageio_1.0</code> metadata format.
  640. *
  641. * <p> This method calls the various <code>getStandard*Node</code>
  642. * methods to supply each of the subtrees rooted at the children
  643. * of the root node. If any of those methods returns
  644. * <code>null</code>, the corresponding subtree will be omitted.
  645. * If all of them return <code>null</code>, a tree consisting of a
  646. * single root node will be returned.
  647. *
  648. * @return an <code>IIOMetadataNode</code> representing the root
  649. * of a metadata tree in the <code>javax_imageio_1.0</code>
  650. * format.
  651. *
  652. * @see #getStandardChromaNode
  653. * @see #getStandardCompressionNode
  654. * @see #getStandardDataNode
  655. * @see #getStandardDimensionNode
  656. * @see #getStandardDocumentNode
  657. * @see #getStandardTextNode
  658. * @see #getStandardTileNode
  659. * @see #getStandardTransparencyNode
  660. */
  661. protected final IIOMetadataNode getStandardTree() {
  662. IIOMetadataNode root = new IIOMetadataNode
  663. (IIOMetadataFormatImpl.standardMetadataFormatName);
  664. append(root, getStandardChromaNode());
  665. append(root, getStandardCompressionNode());
  666. append(root, getStandardDataNode());
  667. append(root, getStandardDimensionNode());
  668. append(root, getStandardDocumentNode());
  669. append(root, getStandardTextNode());
  670. append(root, getStandardTileNode());
  671. append(root, getStandardTransparencyNode());
  672. return root;
  673. }
  674. /**
  675. * Sets the internal state of this <code>IIOMetadata</code> object
  676. * from a tree of XML DOM <code>Node</code>s whose syntax is
  677. * defined by the given metadata format. The previous state is
  678. * discarded. If the tree's structure or contents are invalid, an
  679. * <code>IIOInvalidTreeException</code> will be thrown.
  680. *
  681. * <p> The default implementation calls <code>reset</code>
  682. * followed by <code>mergeTree(formatName, root)</code>.
  683. *
  684. * @param formatName the desired metadata format.
  685. * @param root an XML DOM <code>Node</code> object forming the
  686. * root of a tree.
  687. *
  688. * @exception IllegalStateException if this object is read-only.
  689. * @exception IllegalArgumentException if <code>formatName</code>
  690. * is <code>null</code> or is not one of the names returned by
  691. * <code>getMetadataFormatNames</code>.
  692. * @exception IllegalArgumentException if <code>root</code> is
  693. * <code>null</code>.
  694. * @exception IIOInvalidTreeException if the tree cannot be parsed
  695. * successfully using the rules of the given format.
  696. *
  697. * @see #getMetadataFormatNames
  698. * @see #getAsTree
  699. * @see #mergeTree
  700. */
  701. public void setFromTree(String formatName, Node root)
  702. throws IIOInvalidTreeException {
  703. reset();
  704. mergeTree(formatName, root);
  705. }
  706. /**
  707. * Resets all the data stored in this object to default values,
  708. * usually to the state this object was in immediately after
  709. * construction, though the precise semantics are plug-in specific.
  710. * Note that there are many possible default values, depending on
  711. * how the object was created.
  712. *
  713. * @exception IllegalStateException if this object is read-only.
  714. *
  715. * @see javax.imageio.ImageReader#getStreamMetadata
  716. * @see javax.imageio.ImageReader#getImageMetadata
  717. * @see javax.imageio.ImageWriter#getDefaultStreamMetadata
  718. * @see javax.imageio.ImageWriter#getDefaultImageMetadata
  719. */
  720. public abstract void reset();
  721. /**
  722. * Sets the <code>IIOMetadataController</code> to be used
  723. * to provide settings for this <code>IIOMetadata</code>
  724. * object when the <code>activateController</code> method
  725. * is called, overriding any default controller. If the
  726. * argument is <code>null</code>, no controller will be
  727. * used, including any default. To restore the default, use
  728. * <code>setController(getDefaultController())</code>.
  729. *
  730. * <p> The default implementation sets the <code>controller</code>
  731. * instance variable to the supplied value.
  732. *
  733. * @param controller An appropriate
  734. * <code>IIOMetadataController</code>, or <code>null</code>.
  735. *
  736. * @see IIOMetadataController
  737. * @see #getController
  738. * @see #getDefaultController
  739. * @see #hasController
  740. * @see #activateController()
  741. */
  742. public void setController(IIOMetadataController controller) {
  743. this.controller = controller;
  744. }
  745. /**
  746. * Returns whatever <code>IIOMetadataController</code> is currently
  747. * installed. This could be the default if there is one,
  748. * <code>null</code>, or the argument of the most recent call
  749. * to <code>setController</code>.
  750. *
  751. * <p> The default implementation returns the value of the
  752. * <code>controller</code> instance variable.
  753. *
  754. * @return the currently installed
  755. * <code>IIOMetadataController</code>, or <code>null</code>.
  756. *
  757. * @see IIOMetadataController
  758. * @see #setController
  759. * @see #getDefaultController
  760. * @see #hasController
  761. * @see #activateController()
  762. */
  763. public IIOMetadataController getController() {
  764. return controller;
  765. }
  766. /**
  767. * Returns the default <code>IIOMetadataController</code>, if there
  768. * is one, regardless of the currently installed controller. If
  769. * there is no default controller, returns <code>null</code>.
  770. *
  771. * <p> The default implementation returns the value of the
  772. * <code>defaultController</code> instance variable.
  773. *
  774. * @return the default <code>IIOMetadataController</code>, or
  775. * <code>null</code>.
  776. *
  777. * @see IIOMetadataController
  778. * @see #setController(IIOMetadataController)
  779. * @see #getController
  780. * @see #hasController
  781. * @see #activateController()
  782. */
  783. public IIOMetadataController getDefaultController() {
  784. return defaultController;
  785. }
  786. /**
  787. * Returns <code>true</code> if there is a controller installed
  788. * for this <code>IIOMetadata</code> object.
  789. *
  790. * <p> The default implementation returns <code>true</code> if the
  791. * <code>getController</code> method returns a
  792. * non-<code>null</code> value.
  793. *
  794. * @return <code>true</code> if a controller is installed.
  795. *
  796. * @see IIOMetadataController
  797. * @see #setController(IIOMetadataController)
  798. * @see #getController
  799. * @see #getDefaultController
  800. * @see #activateController()
  801. */
  802. public boolean hasController() {
  803. return (getController() != null);
  804. }
  805. /**
  806. * Activates the installed <code>IIOMetadataController</code> for
  807. * this <code>IIOMetadata</code> object and returns the resulting
  808. * value. When this method returns <code>true</code>, all values for this
  809. * <code>IIOMetadata</code> object will be ready for the next write
  810. * operation. If <code>false</code> is
  811. * returned, no settings in this object will have been disturbed
  812. * (<i>i.e.</i>, the user canceled the operation).
  813. *
  814. * <p> Ordinarily, the controller will be a GUI providing a user
  815. * interface for a subclass of <code>IIOMetadata</code> for a
  816. * particular plug-in. Controllers need not be GUIs, however.
  817. *
  818. * <p> The default implementation calls <code>getController</code>
  819. * and the calls <code>activate</code> on the returned object if
  820. * <code>hasController</code> returns <code>true</code>.
  821. *
  822. * @return <code>true</code> if the controller completed normally.
  823. *
  824. * @exception IllegalStateException if there is no controller
  825. * currently installed.
  826. *
  827. * @see IIOMetadataController
  828. * @see #setController(IIOMetadataController)
  829. * @see #getController
  830. * @see #getDefaultController
  831. * @see #hasController
  832. */
  833. public boolean activateController() {
  834. if (!hasController()) {
  835. throw new IllegalStateException("hasController() == false!");
  836. }
  837. return getController().activate(this);
  838. }
  839. }