jdk/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadataFormatImpl.java
changeset 35667 ed476aba94de
parent 32865 f9cb6e427f9e
child 36511 9d0388c6b336
equal deleted inserted replaced
35666:d69b38870195 35667:ed476aba94de
    37 import javax.imageio.ImageTypeSpecifier;
    37 import javax.imageio.ImageTypeSpecifier;
    38 import com.sun.imageio.plugins.common.StandardMetadataFormat;
    38 import com.sun.imageio.plugins.common.StandardMetadataFormat;
    39 
    39 
    40 /**
    40 /**
    41  * A concrete class providing a reusable implementation of the
    41  * A concrete class providing a reusable implementation of the
    42  * <code>IIOMetadataFormat</code> interface.  In addition, a static
    42  * {@code IIOMetadataFormat} interface.  In addition, a static
    43  * instance representing the standard, plug-in neutral
    43  * instance representing the standard, plug-in neutral
    44  * <code>javax_imageio_1.0</code> format is provided by the
    44  * {@code javax_imageio_1.0} format is provided by the
    45  * <code>getStandardFormatInstance</code> method.
    45  * {@code getStandardFormatInstance} method.
    46  *
    46  *
    47  * <p> In order to supply localized descriptions of elements and
    47  * <p> In order to supply localized descriptions of elements and
    48  * attributes, a <code>ResourceBundle</code> with a base name of
    48  * attributes, a {@code ResourceBundle} with a base name of
    49  * <code>this.getClass().getName() + "Resources"</code> should be
    49  * {@code this.getClass().getName() + "Resources"} should be
    50  * supplied via the usual mechanism used by
    50  * supplied via the usual mechanism used by
    51  * <code>ResourceBundle.getBundle</code>.  Briefly, the subclasser
    51  * {@code ResourceBundle.getBundle}.  Briefly, the subclasser
    52  * supplies one or more additional classes according to a naming
    52  * supplies one or more additional classes according to a naming
    53  * convention (by default, the fully-qualified name of the subclass
    53  * convention (by default, the fully-qualified name of the subclass
    54  * extending <code>IIMetadataFormatImpl</code>, plus the string
    54  * extending {@code IIMetadataFormatImpl}, plus the string
    55  * "Resources", plus the country, language, and variant codes
    55  * "Resources", plus the country, language, and variant codes
    56  * separated by underscores).  At run time, calls to
    56  * separated by underscores).  At run time, calls to
    57  * <code>getElementDescription</code> or
    57  * {@code getElementDescription} or
    58  * <code>getAttributeDescription</code> will attempt to load such
    58  * {@code getAttributeDescription} will attempt to load such
    59  * classes dynamically according to the supplied locale, and will use
    59  * classes dynamically according to the supplied locale, and will use
    60  * either the element name, or the element name followed by a '/'
    60  * either the element name, or the element name followed by a '/'
    61  * character followed by the attribute name as a key.  This key will
    61  * character followed by the attribute name as a key.  This key will
    62  * be supplied to the <code>ResourceBundle</code>'s
    62  * be supplied to the {@code ResourceBundle}'s
    63  * <code>getString</code> method, and the resulting localized
    63  * {@code getString} method, and the resulting localized
    64  * description of the node or attribute is returned.
    64  * description of the node or attribute is returned.
    65  *
    65  *
    66  * <p> The subclass may supply a different base name for the resource
    66  * <p> The subclass may supply a different base name for the resource
    67  * bundles using the <code>setResourceBaseName</code> method.
    67  * bundles using the {@code setResourceBaseName} method.
    68  *
    68  *
    69  * <p> A subclass may choose its own localization mechanism, if so
    69  * <p> A subclass may choose its own localization mechanism, if so
    70  * desired, by overriding the supplied implementations of
    70  * desired, by overriding the supplied implementations of
    71  * <code>getElementDescription</code> and
    71  * {@code getElementDescription} and
    72  * <code>getAttributeDescription</code>.
    72  * {@code getAttributeDescription}.
    73  *
    73  *
    74  * @see ResourceBundle#getBundle(String,Locale)
    74  * @see ResourceBundle#getBundle(String,Locale)
    75  *
    75  *
    76  */
    76  */
    77 public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat {
    77 public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat {
    78 
    78 
    79     /**
    79     /**
    80      * A <code>String</code> constant containing the standard format
    80      * A {@code String} constant containing the standard format
    81      * name, <code>"javax_imageio_1.0"</code>.
    81      * name, {@code "javax_imageio_1.0"}.
    82      */
    82      */
    83     public static final String standardMetadataFormatName =
    83     public static final String standardMetadataFormatName =
    84         "javax_imageio_1.0";
    84         "javax_imageio_1.0";
    85 
    85 
    86     private static IIOMetadataFormat standardFormat = null;
    86     private static IIOMetadataFormat standardFormat = null;
   150         int arrayMinLength = 0;
   150         int arrayMinLength = 0;
   151         int arrayMaxLength = 0;
   151         int arrayMaxLength = 0;
   152     }
   152     }
   153 
   153 
   154     /**
   154     /**
   155      * Constructs a blank <code>IIOMetadataFormatImpl</code> instance,
   155      * Constructs a blank {@code IIOMetadataFormatImpl} instance,
   156      * with a given root element name and child policy (other than
   156      * with a given root element name and child policy (other than
   157      * <code>CHILD_POLICY_REPEAT</code>).  Additional elements, and
   157      * {@code CHILD_POLICY_REPEAT}).  Additional elements, and
   158      * their attributes and <code>Object</code> reference information
   158      * their attributes and {@code Object} reference information
   159      * may be added using the various <code>add</code> methods.
   159      * may be added using the various {@code add} methods.
   160      *
   160      *
   161      * @param rootName the name of the root element.
   161      * @param rootName the name of the root element.
   162      * @param childPolicy one of the <code>CHILD_POLICY_*</code> constants,
   162      * @param childPolicy one of the {@code CHILD_POLICY_*} constants,
   163      * other than <code>CHILD_POLICY_REPEAT</code>.
   163      * other than {@code CHILD_POLICY_REPEAT}.
   164      *
   164      *
   165      * @exception IllegalArgumentException if <code>rootName</code> is
   165      * @exception IllegalArgumentException if {@code rootName} is
   166      * <code>null</code>.
   166      * {@code null}.
   167      * @exception IllegalArgumentException if <code>childPolicy</code> is
   167      * @exception IllegalArgumentException if {@code childPolicy} is
   168      * not one of the predefined constants.
   168      * not one of the predefined constants.
   169      */
   169      */
   170     public IIOMetadataFormatImpl(String rootName,
   170     public IIOMetadataFormatImpl(String rootName,
   171                                  int childPolicy) {
   171                                  int childPolicy) {
   172         if (rootName == null) {
   172         if (rootName == null) {
   186 
   186 
   187         elementMap.put(rootName, root);
   187         elementMap.put(rootName, root);
   188     }
   188     }
   189 
   189 
   190     /**
   190     /**
   191      * Constructs a blank <code>IIOMetadataFormatImpl</code> instance,
   191      * Constructs a blank {@code IIOMetadataFormatImpl} instance,
   192      * with a given root element name and a child policy of
   192      * with a given root element name and a child policy of
   193      * <code>CHILD_POLICY_REPEAT</code>.  Additional elements, and
   193      * {@code CHILD_POLICY_REPEAT}.  Additional elements, and
   194      * their attributes and <code>Object</code> reference information
   194      * their attributes and {@code Object} reference information
   195      * may be added using the various <code>add</code> methods.
   195      * may be added using the various {@code add} methods.
   196      *
   196      *
   197      * @param rootName the name of the root element.
   197      * @param rootName the name of the root element.
   198      * @param minChildren the minimum number of children of the node.
   198      * @param minChildren the minimum number of children of the node.
   199      * @param maxChildren the maximum number of children of the node.
   199      * @param maxChildren the maximum number of children of the node.
   200      *
   200      *
   201      * @exception IllegalArgumentException if <code>rootName</code> is
   201      * @exception IllegalArgumentException if {@code rootName} is
   202      * <code>null</code>.
   202      * {@code null}.
   203      * @exception IllegalArgumentException if <code>minChildren</code>
   203      * @exception IllegalArgumentException if {@code minChildren}
   204      * is negative or larger than <code>maxChildren</code>.
   204      * is negative or larger than {@code maxChildren}.
   205      */
   205      */
   206     public IIOMetadataFormatImpl(String rootName,
   206     public IIOMetadataFormatImpl(String rootName,
   207                                  int minChildren,
   207                                  int minChildren,
   208                                  int maxChildren) {
   208                                  int maxChildren) {
   209         if (rootName == null) {
   209         if (rootName == null) {
   225         this.rootName = rootName;
   225         this.rootName = rootName;
   226         elementMap.put(rootName, root);
   226         elementMap.put(rootName, root);
   227     }
   227     }
   228 
   228 
   229     /**
   229     /**
   230      * Sets a new base name for locating <code>ResourceBundle</code>s
   230      * Sets a new base name for locating {@code ResourceBundle}s
   231      * containing descriptions of elements and attributes for this
   231      * containing descriptions of elements and attributes for this
   232      * format.
   232      * format.
   233      *
   233      *
   234      * <p> Prior to the first time this method is called, the base
   234      * <p> Prior to the first time this method is called, the base
   235      * name will be equal to <code>this.getClass().getName() +
   235      * name will be equal to
   236      * "Resources"</code>.
   236      * {@code this.getClass().getName() + "Resources"}.
   237      *
   237      *
   238      * @param resourceBaseName a <code>String</code> containing the new
   238      * @param resourceBaseName a {@code String} containing the new
   239      * base name.
   239      * base name.
   240      *
   240      *
   241      * @exception IllegalArgumentException if
   241      * @exception IllegalArgumentException if
   242      * <code>resourceBaseName</code> is <code>null</code>.
   242      * {@code resourceBaseName} is {@code null}.
   243      *
   243      *
   244      * @see #getResourceBaseName
   244      * @see #getResourceBaseName
   245      */
   245      */
   246     protected void setResourceBaseName(String resourceBaseName) {
   246     protected void setResourceBaseName(String resourceBaseName) {
   247         if (resourceBaseName == null) {
   247         if (resourceBaseName == null) {
   250         this.resourceBaseName = resourceBaseName;
   250         this.resourceBaseName = resourceBaseName;
   251     }
   251     }
   252 
   252 
   253     /**
   253     /**
   254      * Returns the currently set base name for locating
   254      * Returns the currently set base name for locating
   255      * <code>ResourceBundle</code>s.
   255      * {@code ResourceBundle}s.
   256      *
   256      *
   257      * @return a <code>String</code> containing the base name.
   257      * @return a {@code String} containing the base name.
   258      *
   258      *
   259      * @see #setResourceBaseName
   259      * @see #setResourceBaseName
   260      */
   260      */
   261     protected String getResourceBaseName() {
   261     protected String getResourceBaseName() {
   262         return resourceBaseName;
   262         return resourceBaseName;
   263     }
   263     }
   264 
   264 
   265     /**
   265     /**
   266      * Utility method for locating an element.
   266      * Utility method for locating an element.
   267      *
   267      *
   268      * @param mustAppear if <code>true</code>, throw an
   268      * @param mustAppear if {@code true}, throw an
   269      * <code>IllegalArgumentException</code> if no such node exists;
   269      * {@code IllegalArgumentException} if no such node exists;
   270      * if <code>false</code>, just return null.
   270      * if {@code false}, just return null.
   271      */
   271      */
   272     private Element getElement(String elementName, boolean mustAppear) {
   272     private Element getElement(String elementName, boolean mustAppear) {
   273         if (mustAppear && (elementName == null)) {
   273         if (mustAppear && (elementName == null)) {
   274             throw new IllegalArgumentException("element name is null!");
   274             throw new IllegalArgumentException("element name is null!");
   275         }
   275         }
   298 
   298 
   299     // Setup
   299     // Setup
   300 
   300 
   301     /**
   301     /**
   302      * Adds a new element type to this metadata document format with a
   302      * Adds a new element type to this metadata document format with a
   303      * child policy other than <code>CHILD_POLICY_REPEAT</code>.
   303      * child policy other than {@code CHILD_POLICY_REPEAT}.
   304      *
   304      *
   305      * @param elementName the name of the new element.
   305      * @param elementName the name of the new element.
   306      * @param parentName the name of the element that will be the
   306      * @param parentName the name of the element that will be the
   307      * parent of the new element.
   307      * parent of the new element.
   308      * @param childPolicy one of the <code>CHILD_POLICY_*</code>
   308      * @param childPolicy one of the {@code CHILD_POLICY_*}
   309      * constants, other than <code>CHILD_POLICY_REPEAT</code>,
   309      * constants, other than {@code CHILD_POLICY_REPEAT},
   310      * indicating the child policy of the new element.
   310      * indicating the child policy of the new element.
   311      *
   311      *
   312      * @exception IllegalArgumentException if <code>parentName</code>
   312      * @exception IllegalArgumentException if {@code parentName}
   313      * is <code>null</code>, or is not a legal element name for this
   313      * is {@code null}, or is not a legal element name for this
   314      * format.
   314      * format.
   315      * @exception IllegalArgumentException if <code>childPolicy</code>
   315      * @exception IllegalArgumentException if {@code childPolicy}
   316      * is not one of the predefined constants.
   316      * is not one of the predefined constants.
   317      */
   317      */
   318     protected void addElement(String elementName,
   318     protected void addElement(String elementName,
   319                               String parentName,
   319                               String parentName,
   320                               int childPolicy) {
   320                               int childPolicy) {
   336         elementMap.put(elementName, element);
   336         elementMap.put(elementName, element);
   337     }
   337     }
   338 
   338 
   339     /**
   339     /**
   340      * Adds a new element type to this metadata document format with a
   340      * Adds a new element type to this metadata document format with a
   341      * child policy of <code>CHILD_POLICY_REPEAT</code>.
   341      * child policy of {@code CHILD_POLICY_REPEAT}.
   342      *
   342      *
   343      * @param elementName the name of the new element.
   343      * @param elementName the name of the new element.
   344      * @param parentName the name of the element that will be the
   344      * @param parentName the name of the element that will be the
   345      * parent of the new element.
   345      * parent of the new element.
   346      * @param minChildren the minimum number of children of the node.
   346      * @param minChildren the minimum number of children of the node.
   347      * @param maxChildren the maximum number of children of the node.
   347      * @param maxChildren the maximum number of children of the node.
   348      *
   348      *
   349      * @exception IllegalArgumentException if <code>parentName</code>
   349      * @exception IllegalArgumentException if {@code parentName}
   350      * is <code>null</code>, or is not a legal element name for this
   350      * is {@code null}, or is not a legal element name for this
   351      * format.
   351      * format.
   352      * @exception IllegalArgumentException if <code>minChildren</code>
   352      * @exception IllegalArgumentException if {@code minChildren}
   353      * is negative or larger than <code>maxChildren</code>.
   353      * is negative or larger than {@code maxChildren}.
   354      */
   354      */
   355     protected void addElement(String elementName,
   355     protected void addElement(String elementName,
   356                               String parentName,
   356                               String parentName,
   357                               int minChildren,
   357                               int minChildren,
   358                               int maxChildren) {
   358                               int maxChildren) {
   383      * @param parentName the name of the element that will be the
   383      * @param parentName the name of the element that will be the
   384      * new parent of the element.
   384      * new parent of the element.
   385      * @param elementName the name of the element to be added as a
   385      * @param elementName the name of the element to be added as a
   386      * child.
   386      * child.
   387      *
   387      *
   388      * @exception IllegalArgumentException if <code>elementName</code>
   388      * @exception IllegalArgumentException if {@code elementName}
   389      * is <code>null</code>, or is not a legal element name for this
   389      * is {@code null}, or is not a legal element name for this
   390      * format.
   390      * format.
   391      * @exception IllegalArgumentException if <code>parentName</code>
   391      * @exception IllegalArgumentException if {@code parentName}
   392      * is <code>null</code>, or is not a legal element name for this
   392      * is {@code null}, or is not a legal element name for this
   393      * format.
   393      * format.
   394      */
   394      */
   395     protected void addChildElement(String elementName, String parentName) {
   395     protected void addChildElement(String elementName, String parentName) {
   396         Element parent = getElement(parentName);
   396         Element parent = getElement(parentName);
   397         Element element = getElement(elementName);
   397         Element element = getElement(elementName);
   426      * be set to an arbitrary value.
   426      * be set to an arbitrary value.
   427      *
   427      *
   428      * @param elementName the name of the element.
   428      * @param elementName the name of the element.
   429      * @param attrName the name of the attribute being added.
   429      * @param attrName the name of the attribute being added.
   430      * @param dataType the data type (string format) of the attribute,
   430      * @param dataType the data type (string format) of the attribute,
   431      * one of the <code>DATATYPE_*</code> constants.
   431      * one of the {@code DATATYPE_*} constants.
   432      * @param required <code>true</code> if the attribute must be present.
   432      * @param required {@code true} if the attribute must be present.
   433      * @param defaultValue the default value for the attribute, or
   433      * @param defaultValue the default value for the attribute, or
   434      * <code>null</code>.
   434      * {@code null}.
   435      *
   435      *
   436      * @exception IllegalArgumentException if <code>elementName</code>
   436      * @exception IllegalArgumentException if {@code elementName}
   437      * is <code>null</code>, or is not a legal element name for this
   437      * is {@code null}, or is not a legal element name for this
   438      * format.
   438      * format.
   439      * @exception IllegalArgumentException if <code>attrName</code> is
   439      * @exception IllegalArgumentException if {@code attrName} is
   440      * <code>null</code>.
   440      * {@code null}.
   441      * @exception IllegalArgumentException if <code>dataType</code> is
   441      * @exception IllegalArgumentException if {@code dataType} is
   442      * not one of the predefined constants.
   442      * not one of the predefined constants.
   443      */
   443      */
   444     protected void addAttribute(String elementName,
   444     protected void addAttribute(String elementName,
   445                                 String attrName,
   445                                 String attrName,
   446                                 int dataType,
   446                                 int dataType,
   470      * be defined by a set of enumerated values.
   470      * be defined by a set of enumerated values.
   471      *
   471      *
   472      * @param elementName the name of the element.
   472      * @param elementName the name of the element.
   473      * @param attrName the name of the attribute being added.
   473      * @param attrName the name of the attribute being added.
   474      * @param dataType the data type (string format) of the attribute,
   474      * @param dataType the data type (string format) of the attribute,
   475      * one of the <code>DATATYPE_*</code> constants.
   475      * one of the {@code DATATYPE_*} constants.
   476      * @param required <code>true</code> if the attribute must be present.
   476      * @param required {@code true} if the attribute must be present.
   477      * @param defaultValue the default value for the attribute, or
   477      * @param defaultValue the default value for the attribute, or
   478      * <code>null</code>.
   478      * {@code null}.
   479      * @param enumeratedValues a <code>List</code> of
   479      * @param enumeratedValues a {@code List} of
   480      * <code>String</code>s containing the legal values for the
   480      * {@code String}s containing the legal values for the
   481      * attribute.
   481      * attribute.
   482      *
   482      *
   483      * @exception IllegalArgumentException if <code>elementName</code>
   483      * @exception IllegalArgumentException if {@code elementName}
   484      * is <code>null</code>, or is not a legal element name for this
   484      * is {@code null}, or is not a legal element name for this
   485      * format.
   485      * format.
   486      * @exception IllegalArgumentException if <code>attrName</code> is
   486      * @exception IllegalArgumentException if {@code attrName} is
   487      * <code>null</code>.
   487      * {@code null}.
   488      * @exception IllegalArgumentException if <code>dataType</code> is
   488      * @exception IllegalArgumentException if {@code dataType} is
   489      * not one of the predefined constants.
   489      * not one of the predefined constants.
   490      * @exception IllegalArgumentException if
   490      * @exception IllegalArgumentException if
   491      * <code>enumeratedValues</code> is <code>null</code>.
   491      * {@code enumeratedValues} is {@code null}.
   492      * @exception IllegalArgumentException if
   492      * @exception IllegalArgumentException if
   493      * <code>enumeratedValues</code> does not contain at least one
   493      * {@code enumeratedValues} does not contain at least one
   494      * entry.
   494      * entry.
   495      * @exception IllegalArgumentException if
   495      * @exception IllegalArgumentException if
   496      * <code>enumeratedValues</code> contains an element that is not a
   496      * {@code enumeratedValues} contains an element that is not a
   497      * <code>String</code> or is <code>null</code>.
   497      * {@code String} or is {@code null}.
   498      */
   498      */
   499     protected void addAttribute(String elementName,
   499     protected void addAttribute(String elementName,
   500                                 String attrName,
   500                                 String attrName,
   501                                 int dataType,
   501                                 int dataType,
   502                                 boolean required,
   502                                 boolean required,
   545      * be defined by a range of values.
   545      * be defined by a range of values.
   546      *
   546      *
   547      * @param elementName the name of the element.
   547      * @param elementName the name of the element.
   548      * @param attrName the name of the attribute being added.
   548      * @param attrName the name of the attribute being added.
   549      * @param dataType the data type (string format) of the attribute,
   549      * @param dataType the data type (string format) of the attribute,
   550      * one of the <code>DATATYPE_*</code> constants.
   550      * one of the {@code DATATYPE_*} constants.
   551      * @param required <code>true</code> if the attribute must be present.
   551      * @param required {@code true} if the attribute must be present.
   552      * @param defaultValue the default value for the attribute, or
   552      * @param defaultValue the default value for the attribute, or
   553      * <code>null</code>.
   553      * {@code null}.
   554      * @param minValue the smallest (inclusive or exclusive depending
   554      * @param minValue the smallest (inclusive or exclusive depending
   555      * on the value of <code>minInclusive</code>) legal value for the
   555      * on the value of {@code minInclusive}) legal value for the
   556      * attribute, as a <code>String</code>.
   556      * attribute, as a {@code String}.
   557      * @param maxValue the largest (inclusive or exclusive depending
   557      * @param maxValue the largest (inclusive or exclusive depending
   558      * on the value of <code>minInclusive</code>) legal value for the
   558      * on the value of {@code minInclusive}) legal value for the
   559      * attribute, as a <code>String</code>.
   559      * attribute, as a {@code String}.
   560      * @param minInclusive <code>true</code> if <code>minValue</code>
   560      * @param minInclusive {@code true} if {@code minValue}
   561      * is inclusive.
   561      * is inclusive.
   562      * @param maxInclusive <code>true</code> if <code>maxValue</code>
   562      * @param maxInclusive {@code true} if {@code maxValue}
   563      * is inclusive.
   563      * is inclusive.
   564      *
   564      *
   565      * @exception IllegalArgumentException if <code>elementName</code>
   565      * @exception IllegalArgumentException if {@code elementName}
   566      * is <code>null</code>, or is not a legal element name for this
   566      * is {@code null}, or is not a legal element name for this
   567      * format.
   567      * format.
   568      * @exception IllegalArgumentException if <code>attrName</code> is
   568      * @exception IllegalArgumentException if {@code attrName} is
   569      * <code>null</code>.
   569      * {@code null}.
   570      * @exception IllegalArgumentException if <code>dataType</code> is
   570      * @exception IllegalArgumentException if {@code dataType} is
   571      * not one of the predefined constants.
   571      * not one of the predefined constants.
   572      */
   572      */
   573     protected void addAttribute(String elementName,
   573     protected void addAttribute(String elementName,
   574                                 String attrName,
   574                                 String attrName,
   575                                 int dataType,
   575                                 int dataType,
   611      * be defined by a list of values.
   611      * be defined by a list of values.
   612      *
   612      *
   613      * @param elementName the name of the element.
   613      * @param elementName the name of the element.
   614      * @param attrName the name of the attribute being added.
   614      * @param attrName the name of the attribute being added.
   615      * @param dataType the data type (string format) of the attribute,
   615      * @param dataType the data type (string format) of the attribute,
   616      * one of the <code>DATATYPE_*</code> constants.
   616      * one of the {@code DATATYPE_*} constants.
   617      * @param required <code>true</code> if the attribute must be present.
   617      * @param required {@code true} if the attribute must be present.
   618      * @param listMinLength the smallest legal number of list items.
   618      * @param listMinLength the smallest legal number of list items.
   619      * @param listMaxLength the largest legal number of list items.
   619      * @param listMaxLength the largest legal number of list items.
   620      *
   620      *
   621      * @exception IllegalArgumentException if <code>elementName</code>
   621      * @exception IllegalArgumentException if {@code elementName}
   622      * is <code>null</code>, or is not a legal element name for this
   622      * is {@code null}, or is not a legal element name for this
   623      * format.
   623      * format.
   624      * @exception IllegalArgumentException if <code>attrName</code> is
   624      * @exception IllegalArgumentException if {@code attrName} is
   625      * <code>null</code>.
   625      * {@code null}.
   626      * @exception IllegalArgumentException if <code>dataType</code> is
   626      * @exception IllegalArgumentException if {@code dataType} is
   627      * not one of the predefined constants.
   627      * not one of the predefined constants.
   628      * @exception IllegalArgumentException if
   628      * @exception IllegalArgumentException if
   629      * <code>listMinLength</code> is negative or larger than
   629      * {@code listMinLength} is negative or larger than
   630      * <code>listMaxLength</code>.
   630      * {@code listMaxLength}.
   631      */
   631      */
   632     protected void addAttribute(String elementName,
   632     protected void addAttribute(String elementName,
   633                                 String attrName,
   633                                 String attrName,
   634                                 int dataType,
   634                                 int dataType,
   635                                 boolean required,
   635                                 boolean required,
   658         element.attrMap.put(attrName, attr);
   658         element.attrMap.put(attrName, attr);
   659     }
   659     }
   660 
   660 
   661     /**
   661     /**
   662      * Adds a new attribute to a previously defined element that will
   662      * Adds a new attribute to a previously defined element that will
   663      * be defined by the enumerated values <code>TRUE</code> and
   663      * be defined by the enumerated values {@code TRUE} and
   664      * <code>FALSE</code>, with a datatype of
   664      * {@code FALSE}, with a datatype of
   665      * <code>DATATYPE_BOOLEAN</code>.
   665      * {@code DATATYPE_BOOLEAN}.
   666      *
   666      *
   667      * @param elementName the name of the element.
   667      * @param elementName the name of the element.
   668      * @param attrName the name of the attribute being added.
   668      * @param attrName the name of the attribute being added.
   669      * @param hasDefaultValue <code>true</code> if a default value
   669      * @param hasDefaultValue {@code true} if a default value
   670      * should be present.
   670      * should be present.
   671      * @param defaultValue the default value for the attribute as a
   671      * @param defaultValue the default value for the attribute as a
   672      * <code>boolean</code>, ignored if <code>hasDefaultValue</code>
   672      * {@code boolean}, ignored if {@code hasDefaultValue}
   673      * is <code>false</code>.
   673      * is {@code false}.
   674      *
   674      *
   675      * @exception IllegalArgumentException if <code>elementName</code>
   675      * @exception IllegalArgumentException if {@code elementName}
   676      * is <code>null</code>, or is not a legal element name for this
   676      * is {@code null}, or is not a legal element name for this
   677      * format.
   677      * format.
   678      * @exception IllegalArgumentException if <code>attrName</code> is
   678      * @exception IllegalArgumentException if {@code attrName} is
   679      * <code>null</code>.
   679      * {@code null}.
   680      */
   680      */
   681     protected void addBooleanAttribute(String elementName,
   681     protected void addBooleanAttribute(String elementName,
   682                                        String attrName,
   682                                        String attrName,
   683                                        boolean hasDefaultValue,
   683                                        boolean hasDefaultValue,
   684                                        boolean defaultValue) {
   684                                        boolean defaultValue) {
   704      * nothing happens and no exception is thrown.
   704      * nothing happens and no exception is thrown.
   705      *
   705      *
   706      * @param elementName the name of the element.
   706      * @param elementName the name of the element.
   707      * @param attrName the name of the attribute being removed.
   707      * @param attrName the name of the attribute being removed.
   708      *
   708      *
   709      * @exception IllegalArgumentException if <code>elementName</code>
   709      * @exception IllegalArgumentException if {@code elementName}
   710      * is <code>null</code>, or is not a legal element name for this format.
   710      * is {@code null}, or is not a legal element name for this format.
   711      */
   711      */
   712     protected void removeAttribute(String elementName, String attrName) {
   712     protected void removeAttribute(String elementName, String attrName) {
   713         Element element = getElement(elementName);
   713         Element element = getElement(elementName);
   714         element.attrList.remove(attrName);
   714         element.attrList.remove(attrName);
   715         element.attrMap.remove(attrName);
   715         element.attrMap.remove(attrName);
   716     }
   716     }
   717 
   717 
   718     /**
   718     /**
   719      * Allows an <code>Object</code> reference of a given class type
   719      * Allows an {@code Object} reference of a given class type
   720      * to be stored in nodes implementing the named element.  The
   720      * to be stored in nodes implementing the named element.  The
   721      * value of the <code>Object</code> is unconstrained other than by
   721      * value of the {@code Object} is unconstrained other than by
   722      * its class type.
   722      * its class type.
   723      *
   723      *
   724      * <p> If an <code>Object</code> reference was previously allowed,
   724      * <p> If an {@code Object} reference was previously allowed,
   725      * the previous settings are overwritten.
   725      * the previous settings are overwritten.
   726      *
   726      *
   727      * @param elementName the name of the element.
   727      * @param elementName the name of the element.
   728      * @param classType a <code>Class</code> variable indicating the
   728      * @param classType a {@code Class} variable indicating the
   729      * legal class type for the object value.
   729      * legal class type for the object value.
   730      * @param required <code>true</code> if an object value must be present.
   730      * @param required {@code true} if an object value must be present.
   731      * @param defaultValue the default value for the
   731      * @param defaultValue the default value for the
   732      * <code>Object</code> reference, or <code>null</code>.
   732      * {@code Object} reference, or {@code null}.
   733      * @param <T> the type of the object.
   733      * @param <T> the type of the object.
   734      *
   734      *
   735      * @exception IllegalArgumentException if <code>elementName</code>
   735      * @exception IllegalArgumentException if {@code elementName}
   736      * is <code>null</code>, or is not a legal element name for this format.
   736      * is {@code null}, or is not a legal element name for this format.
   737      */
   737      */
   738     protected <T> void addObjectValue(String elementName,
   738     protected <T> void addObjectValue(String elementName,
   739                                       Class<T> classType,
   739                                       Class<T> classType,
   740                                       boolean required,
   740                                       boolean required,
   741                                       T defaultValue)
   741                                       T defaultValue)
   748 
   748 
   749         element.objectValue = obj;
   749         element.objectValue = obj;
   750     }
   750     }
   751 
   751 
   752     /**
   752     /**
   753      * Allows an <code>Object</code> reference of a given class type
   753      * Allows an {@code Object} reference of a given class type
   754      * to be stored in nodes implementing the named element.  The
   754      * to be stored in nodes implementing the named element.  The
   755      * value of the <code>Object</code> must be one of the values
   755      * value of the {@code Object} must be one of the values
   756      * given by <code>enumeratedValues</code>.
   756      * given by {@code enumeratedValues}.
   757      *
   757      *
   758      * <p> If an <code>Object</code> reference was previously allowed,
   758      * <p> If an {@code Object} reference was previously allowed,
   759      * the previous settings are overwritten.
   759      * the previous settings are overwritten.
   760      *
   760      *
   761      * @param elementName the name of the element.
   761      * @param elementName the name of the element.
   762      * @param classType a <code>Class</code> variable indicating the
   762      * @param classType a {@code Class} variable indicating the
   763      * legal class type for the object value.
   763      * legal class type for the object value.
   764      * @param required <code>true</code> if an object value must be present.
   764      * @param required {@code true} if an object value must be present.
   765      * @param defaultValue the default value for the
   765      * @param defaultValue the default value for the
   766      * <code>Object</code> reference, or <code>null</code>.
   766      * {@code Object} reference, or {@code null}.
   767      * @param enumeratedValues a <code>List</code> of
   767      * @param enumeratedValues a {@code List} of
   768      * <code>Object</code>s containing the legal values for the
   768      * {@code Object}s containing the legal values for the
   769      * object reference.
   769      * object reference.
   770      * @param <T> the type of the object.
   770      * @param <T> the type of the object.
   771      *
   771      *
   772      * @exception IllegalArgumentException if <code>elementName</code>
   772      * @exception IllegalArgumentException if {@code elementName}
   773      * is <code>null</code>, or is not a legal element name for this format.
   773      * is {@code null}, or is not a legal element name for this format.
   774      * @exception IllegalArgumentException if
   774      * @exception IllegalArgumentException if
   775      * <code>enumeratedValues</code> is <code>null</code>.
   775      * {@code enumeratedValues} is {@code null}.
   776      * @exception IllegalArgumentException if
   776      * @exception IllegalArgumentException if
   777      * <code>enumeratedValues</code> does not contain at least one
   777      * {@code enumeratedValues} does not contain at least one
   778      * entry.
   778      * entry.
   779      * @exception IllegalArgumentException if
   779      * @exception IllegalArgumentException if
   780      * <code>enumeratedValues</code> contains an element that is not
   780      * {@code enumeratedValues} contains an element that is not
   781      * an instance of the class type denoted by <code>classType</code>
   781      * an instance of the class type denoted by {@code classType}
   782      * or is <code>null</code>.
   782      * or is {@code null}.
   783      */
   783      */
   784     protected <T> void addObjectValue(String elementName,
   784     protected <T> void addObjectValue(String elementName,
   785                                       Class<T> classType,
   785                                       Class<T> classType,
   786                                       boolean required,
   786                                       boolean required,
   787                                       T defaultValue,
   787                                       T defaultValue,
   813 
   813 
   814         element.objectValue = obj;
   814         element.objectValue = obj;
   815     }
   815     }
   816 
   816 
   817     /**
   817     /**
   818      * Allows an <code>Object</code> reference of a given class type
   818      * Allows an {@code Object} reference of a given class type
   819      * to be stored in nodes implementing the named element.  The
   819      * to be stored in nodes implementing the named element.  The
   820      * value of the <code>Object</code> must be within the range given
   820      * value of the {@code Object} must be within the range given
   821      * by <code>minValue</code> and <code>maxValue</code>.
   821      * by {@code minValue} and {@code maxValue}.
   822      * Furthermore, the class type must implement the
   822      * Furthermore, the class type must implement the
   823      * <code>Comparable</code> interface.
   823      * {@code Comparable} interface.
   824      *
   824      *
   825      * <p> If an <code>Object</code> reference was previously allowed,
   825      * <p> If an {@code Object} reference was previously allowed,
   826      * the previous settings are overwritten.
   826      * the previous settings are overwritten.
   827      *
   827      *
   828      * @param elementName the name of the element.
   828      * @param elementName the name of the element.
   829      * @param classType a <code>Class</code> variable indicating the
   829      * @param classType a {@code Class} variable indicating the
   830      * legal class type for the object value.
   830      * legal class type for the object value.
   831      * @param defaultValue the default value for the
   831      * @param defaultValue the default value for the
   832      * @param minValue the smallest (inclusive or exclusive depending
   832      * @param minValue the smallest (inclusive or exclusive depending
   833      * on the value of <code>minInclusive</code>) legal value for the
   833      * on the value of {@code minInclusive}) legal value for the
   834      * object value, as a <code>String</code>.
   834      * object value, as a {@code String}.
   835      * @param maxValue the largest (inclusive or exclusive depending
   835      * @param maxValue the largest (inclusive or exclusive depending
   836      * on the value of <code>minInclusive</code>) legal value for the
   836      * on the value of {@code minInclusive}) legal value for the
   837      * object value, as a <code>String</code>.
   837      * object value, as a {@code String}.
   838      * @param minInclusive <code>true</code> if <code>minValue</code>
   838      * @param minInclusive {@code true} if {@code minValue}
   839      * is inclusive.
   839      * is inclusive.
   840      * @param maxInclusive <code>true</code> if <code>maxValue</code>
   840      * @param maxInclusive {@code true} if {@code maxValue}
   841      * is inclusive.
   841      * is inclusive.
   842      * @param <T> the type of the object.
   842      * @param <T> the type of the object.
   843      *
   843      *
   844      * @exception IllegalArgumentException if <code>elementName</code>
   844      * @exception IllegalArgumentException if {@code elementName}
   845      * is <code>null</code>, or is not a legal element name for this
   845      * is {@code null}, or is not a legal element name for this
   846      * format.
   846      * format.
   847      */
   847      */
   848     protected <T extends Object & Comparable<? super T>> void
   848     protected <T extends Object & Comparable<? super T>> void
   849         addObjectValue(String elementName,
   849         addObjectValue(String elementName,
   850                        Class<T> classType,
   850                        Class<T> classType,
   870 
   870 
   871         element.objectValue = obj;
   871         element.objectValue = obj;
   872     }
   872     }
   873 
   873 
   874     /**
   874     /**
   875      * Allows an <code>Object</code> reference of a given class type
   875      * Allows an {@code Object} reference of a given class type
   876      * to be stored in nodes implementing the named element.  The
   876      * to be stored in nodes implementing the named element.  The
   877      * value of the <code>Object</code> must an array of objects of
   877      * value of the {@code Object} must an array of objects of
   878      * class type given by <code>classType</code>, with at least
   878      * class type given by {@code classType}, with at least
   879      * <code>arrayMinLength</code> and at most
   879      * {@code arrayMinLength} and at most
   880      * <code>arrayMaxLength</code> elements.
   880      * {@code arrayMaxLength} elements.
   881      *
   881      *
   882      * <p> If an <code>Object</code> reference was previously allowed,
   882      * <p> If an {@code Object} reference was previously allowed,
   883      * the previous settings are overwritten.
   883      * the previous settings are overwritten.
   884      *
   884      *
   885      * @param elementName the name of the element.
   885      * @param elementName the name of the element.
   886      * @param classType a <code>Class</code> variable indicating the
   886      * @param classType a {@code Class} variable indicating the
   887      * legal class type for the object value.
   887      * legal class type for the object value.
   888      * @param arrayMinLength the smallest legal length for the array.
   888      * @param arrayMinLength the smallest legal length for the array.
   889      * @param arrayMaxLength the largest legal length for the array.
   889      * @param arrayMaxLength the largest legal length for the array.
   890      *
   890      *
   891      * @exception IllegalArgumentException if <code>elementName</code> is
   891      * @exception IllegalArgumentException if {@code elementName} is
   892      * not a legal element name for this format.
   892      * not a legal element name for this format.
   893      */
   893      */
   894     protected void addObjectValue(String elementName,
   894     protected void addObjectValue(String elementName,
   895                                   Class<?> classType,
   895                                   Class<?> classType,
   896                                   int arrayMinLength,
   896                                   int arrayMinLength,
   904 
   904 
   905         element.objectValue = obj;
   905         element.objectValue = obj;
   906     }
   906     }
   907 
   907 
   908     /**
   908     /**
   909      * Disallows an <code>Object</code> reference from being stored in
   909      * Disallows an {@code Object} reference from being stored in
   910      * nodes implementing the named element.
   910      * nodes implementing the named element.
   911      *
   911      *
   912      * @param elementName the name of the element.
   912      * @param elementName the name of the element.
   913      *
   913      *
   914      * @exception IllegalArgumentException if <code>elementName</code> is
   914      * @exception IllegalArgumentException if {@code elementName} is
   915      * not a legal element name for this format.
   915      * not a legal element name for this format.
   916      */
   916      */
   917     protected void removeObjectValue(String elementName) {
   917     protected void removeObjectValue(String elementName) {
   918         Element element = getElement(elementName);
   918         Element element = getElement(elementName);
   919         element.objectValue = null;
   919         element.objectValue = null;
   989             return null;
   989             return null;
   990         }
   990         }
   991     }
   991     }
   992 
   992 
   993     /**
   993     /**
   994      * Returns a <code>String</code> containing a description of the
   994      * Returns a {@code String} containing a description of the
   995      * named element, or <code>null</code>.  The description will be
   995      * named element, or {@code null}.  The description will be
   996      * localized for the supplied <code>Locale</code> if possible.
   996      * localized for the supplied {@code Locale} if possible.
   997      *
   997      *
   998      * <p> The default implementation will first locate a
   998      * <p> The default implementation will first locate a
   999      * <code>ResourceBundle</code> using the current resource base
   999      * {@code ResourceBundle} using the current resource base
  1000      * name set by <code>setResourceBaseName</code> and the supplied
  1000      * name set by {@code setResourceBaseName} and the supplied
  1001      * <code>Locale</code>, using the fallback mechanism described in
  1001      * {@code Locale}, using the fallback mechanism described in
  1002      * the comments for <code>ResourceBundle.getBundle</code>.  If a
  1002      * the comments for {@code ResourceBundle.getBundle}.  If a
  1003      * <code>ResourceBundle</code> is found, the element name will be
  1003      * {@code ResourceBundle} is found, the element name will be
  1004      * used as a key to its <code>getString</code> method, and the
  1004      * used as a key to its {@code getString} method, and the
  1005      * result returned.  If no <code>ResourceBundle</code> is found,
  1005      * result returned.  If no {@code ResourceBundle} is found,
  1006      * or no such key is present, <code>null</code> will be returned.
  1006      * or no such key is present, {@code null} will be returned.
  1007      *
  1007      *
  1008      * <p> If <code>locale</code> is <code>null</code>, the current
  1008      * <p> If {@code locale} is {@code null}, the current
  1009      * default <code>Locale</code> returned by <code>Locale.getLocale</code>
  1009      * default {@code Locale} returned by {@code Locale.getLocale}
  1010      * will be used.
  1010      * will be used.
  1011      *
  1011      *
  1012      * @param elementName the name of the element.
  1012      * @param elementName the name of the element.
  1013      * @param locale the <code>Locale</code> for which localization
  1013      * @param locale the {@code Locale} for which localization
  1014      * will be attempted.
  1014      * will be attempted.
  1015      *
  1015      *
  1016      * @return the element description.
  1016      * @return the element description.
  1017      *
  1017      *
  1018      * @exception IllegalArgumentException if <code>elementName</code>
  1018      * @exception IllegalArgumentException if {@code elementName}
  1019      * is <code>null</code>, or is not a legal element name for this format.
  1019      * is {@code null}, or is not a legal element name for this format.
  1020      *
  1020      *
  1021      * @see #setResourceBaseName
  1021      * @see #setResourceBaseName
  1022      */
  1022      */
  1023     public String getElementDescription(String elementName,
  1023     public String getElementDescription(String elementName,
  1024                                         Locale locale) {
  1024                                         Locale locale) {
  1126 
  1126 
  1127         return attr.listMaxLength;
  1127         return attr.listMaxLength;
  1128     }
  1128     }
  1129 
  1129 
  1130     /**
  1130     /**
  1131      * Returns a <code>String</code> containing a description of the
  1131      * Returns a {@code String} containing a description of the
  1132      * named attribute, or <code>null</code>.  The description will be
  1132      * named attribute, or {@code null}.  The description will be
  1133      * localized for the supplied <code>Locale</code> if possible.
  1133      * localized for the supplied {@code Locale} if possible.
  1134      *
  1134      *
  1135      * <p> The default implementation will first locate a
  1135      * <p> The default implementation will first locate a
  1136      * <code>ResourceBundle</code> using the current resource base
  1136      * {@code ResourceBundle} using the current resource base
  1137      * name set by <code>setResourceBaseName</code> and the supplied
  1137      * name set by {@code setResourceBaseName} and the supplied
  1138      * <code>Locale</code>, using the fallback mechanism described in
  1138      * {@code Locale}, using the fallback mechanism described in
  1139      * the comments for <code>ResourceBundle.getBundle</code>.  If a
  1139      * the comments for {@code ResourceBundle.getBundle}.  If a
  1140      * <code>ResourceBundle</code> is found, the element name followed
  1140      * {@code ResourceBundle} is found, the element name followed
  1141      * by a "/" character followed by the attribute name
  1141      * by a "/" character followed by the attribute name
  1142      * (<code>elementName + "/" + attrName</code>) will be used as a
  1142      * ({@code elementName + "/" + attrName}) will be used as a
  1143      * key to its <code>getString</code> method, and the result
  1143      * key to its {@code getString} method, and the result
  1144      * returned.  If no <code>ResourceBundle</code> is found, or no
  1144      * returned.  If no {@code ResourceBundle} is found, or no
  1145      * such key is present, <code>null</code> will be returned.
  1145      * such key is present, {@code null} will be returned.
  1146      *
  1146      *
  1147      * <p> If <code>locale</code> is <code>null</code>, the current
  1147      * <p> If {@code locale} is {@code null}, the current
  1148      * default <code>Locale</code> returned by <code>Locale.getLocale</code>
  1148      * default {@code Locale} returned by {@code Locale.getLocale}
  1149      * will be used.
  1149      * will be used.
  1150      *
  1150      *
  1151      * @param elementName the name of the element.
  1151      * @param elementName the name of the element.
  1152      * @param attrName the name of the attribute.
  1152      * @param attrName the name of the attribute.
  1153      * @param locale the <code>Locale</code> for which localization
  1153      * @param locale the {@code Locale} for which localization
  1154      * will be attempted, or <code>null</code>.
  1154      * will be attempted, or {@code null}.
  1155      *
  1155      *
  1156      * @return the attribute description.
  1156      * @return the attribute description.
  1157      *
  1157      *
  1158      * @exception IllegalArgumentException if <code>elementName</code>
  1158      * @exception IllegalArgumentException if {@code elementName}
  1159      * is <code>null</code>, or is not a legal element name for this format.
  1159      * is {@code null}, or is not a legal element name for this format.
  1160      * @exception IllegalArgumentException if <code>attrName</code> is
  1160      * @exception IllegalArgumentException if {@code attrName} is
  1161      * <code>null</code> or is not a legal attribute name for this
  1161      * {@code null} or is not a legal attribute name for this
  1162      * element.
  1162      * element.
  1163      *
  1163      *
  1164      * @see #setResourceBaseName
  1164      * @see #setResourceBaseName
  1165      */
  1165      */
  1166     public String getAttributeDescription(String elementName,
  1166     public String getAttributeDescription(String elementName,
  1257             standardFormat = new StandardMetadataFormat();
  1257             standardFormat = new StandardMetadataFormat();
  1258         }
  1258         }
  1259     }
  1259     }
  1260 
  1260 
  1261     /**
  1261     /**
  1262      * Returns an <code>IIOMetadataFormat</code> object describing the
  1262      * Returns an {@code IIOMetadataFormat} object describing the
  1263      * standard, plug-in neutral <code>javax.imageio_1.0</code>
  1263      * standard, plug-in neutral {@code javax.imageio_1.0}
  1264      * metadata document format described in the comment of the
  1264      * metadata document format described in the comment of the
  1265      * <code>javax.imageio.metadata</code> package.
  1265      * {@code javax.imageio.metadata} package.
  1266      *
  1266      *
  1267      * @return a predefined <code>IIOMetadataFormat</code> instance.
  1267      * @return a predefined {@code IIOMetadataFormat} instance.
  1268      */
  1268      */
  1269     public static IIOMetadataFormat getStandardFormatInstance() {
  1269     public static IIOMetadataFormat getStandardFormatInstance() {
  1270         createStandardFormat();
  1270         createStandardFormat();
  1271         return standardFormat;
  1271         return standardFormat;
  1272     }
  1272     }