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