001    /* IIOMetadataFormatImpl.java --
002       Copyright (C) 2004  Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.imageio.metadata;
040    
041    import org.w3c.dom.Attr;
042    import org.w3c.dom.Element;
043    import org.w3c.dom.NamedNodeMap;
044    import org.w3c.dom.NodeList;
045    import org.w3c.dom.TypeInfo;
046    import java.util.ArrayList;
047    import java.util.HashMap;
048    import java.util.Map;
049    import java.util.List;
050    import java.util.Locale;
051    import java.util.ResourceBundle;
052    import java.util.MissingResourceException;
053    import javax.imageio.ImageTypeSpecifier;
054    
055    public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat
056    {
057      /**
058       * The standard metadata format name constant set to
059       * "javax_imageio_1.0".
060       */
061      public static final String standardMetadataFormatName = "javax_imageio_1.0";
062    
063      private String rootName;
064    
065      // These maps assume that each element name is unique.
066    
067      private Map nodes = new HashMap();
068    
069      // A mapping from element name to child policy.
070      private Map childPolicies = new HashMap();
071    
072      // A mapping from element name to the permissible number of
073      // children.  Values in this map are length-two integer arrays; the
074      // first index is the minimum bound, the second index is the maximum
075      // bound.
076      private Map childRanges = new HashMap();
077    
078      private String resourceBaseName;
079    
080      // Package-private so that it may be used in IIOMetadataNode.
081      static class IIOMetadataNodeAttr extends IIOMetadataNode
082        implements Attr
083      {
084        protected Element owner;
085        protected String name;
086        protected int dataType;
087        protected boolean required;
088        protected String defaultValue;
089    
090        public IIOMetadataNodeAttr (Element owner,
091                                    String name,
092                                    String defaultValue)
093        {
094          this (owner, name, IIOMetadataFormat.DATATYPE_STRING,
095                true, defaultValue);
096        }
097    
098        public IIOMetadataNodeAttr (Element owner,
099                                    String name,
100                                    int dataType,
101                                    boolean required,
102                                    String defaultValue)
103        {
104          this.owner = owner;
105          this.name = name;
106          this.dataType = dataType;
107          this.required = required;
108          this.defaultValue = defaultValue;
109        }
110    
111        public String getName ()
112        {
113          return name;
114        }
115    
116        public Element getOwnerElement ()
117        {
118          return owner;
119        }
120    
121        public int getDataType ()
122        {
123          return dataType;
124        }
125    
126        public TypeInfo getSchemaTypeInfo ()
127        {
128          return null;
129        }
130    
131        public boolean getSpecified ()
132        {
133          return false;
134        }
135    
136        public String getValue ()
137        {
138          return defaultValue;
139        }
140    
141        public boolean isId()
142        {
143          return false;
144        }
145    
146        public void setValue (String value)
147        {
148        }
149    
150        // new methods
151    
152        public boolean isRequired ()
153        {
154          return required;
155        }
156      }
157    
158      private class IIOMetadataNodeAttrEnumerated extends IIOMetadataNodeAttr
159      {
160        protected List enumeratedValues;
161    
162        public IIOMetadataNodeAttrEnumerated (Element owner,
163                                              String name,
164                                              int dataType,
165                                              boolean required,
166                                              String defaultValue,
167                                              List enumeratedValues)
168        {
169          super (owner, name, dataType, required, defaultValue);
170          this.enumeratedValues = new ArrayList (enumeratedValues);
171        }
172    
173        public Object[] getEnumerations ()
174        {
175          return enumeratedValues.toArray ();
176        }
177      }
178    
179      private class IIOMetadataNodeAttrBounded extends IIOMetadataNodeAttr
180      {
181        protected String minValue;
182        protected String maxValue;
183        protected boolean minInclusive;
184        protected boolean maxInclusive;
185    
186        public IIOMetadataNodeAttrBounded (Element owner,
187                                           String name,
188                                           int dataType,
189                                           boolean required,
190                                           String defaultValue,
191                                           String minValue,
192                                           String maxValue,
193                                           boolean minInclusive,
194                                           boolean maxInclusive)
195        {
196          super (owner, name, dataType, required, defaultValue);
197          this.minValue = minValue;
198          this.maxValue = maxValue;
199          this.minInclusive = minInclusive;
200          this.maxInclusive = maxInclusive;
201        }
202    
203        public String getMinValue ()
204        {
205          return minValue;
206        }
207    
208        public String getMaxValue ()
209        {
210          return maxValue;
211        }
212      }
213    
214      private class IIOMetadataNodeAttrList extends IIOMetadataNodeAttr
215      {
216        protected int listMinLength;
217        protected int listMaxLength;
218    
219        public IIOMetadataNodeAttrList (Element owner,
220                                        String name,
221                                        int dataType,
222                                        boolean required,
223                                        int listMinLength,
224                                        int listMaxLength)
225        {
226          super (owner, name, dataType, required, null);
227          this.listMinLength = listMinLength;
228          this.listMaxLength = listMaxLength;
229        }
230    
231        public int getListMinLength ()
232        {
233          return listMinLength;
234        }
235    
236        public int getListMaxLength ()
237        {
238          return listMaxLength;
239        }
240      }
241    
242      private class NodeObject
243      {
244        protected Element owner;
245        protected Class classType;
246        protected boolean required;
247        protected Object defaultValue;
248        protected int valueType;
249    
250        public NodeObject (Element owner,
251                           Class classType,
252                           boolean required,
253                           Object defaultValue)
254        {
255          this.owner = owner;
256          this.classType = classType;
257          this.required = required;
258          this.defaultValue = defaultValue;
259          valueType = IIOMetadataFormat.VALUE_ARBITRARY;
260        }
261    
262        public int getValueType ()
263        {
264          return valueType;
265        }
266    
267        public Class getClassType ()
268        {
269          return classType;
270        }
271    
272        public Element getOwnerElement ()
273        {
274          return owner;
275        }
276    
277        public Object getDefaultValue ()
278        {
279          return defaultValue;
280        }
281    
282        public boolean isRequired ()
283        {
284          return required;
285        }
286      }
287    
288      private class NodeObjectEnumerated extends NodeObject
289      {
290        protected List enumeratedValues;
291    
292        public NodeObjectEnumerated (Element owner,
293                                     Class classType,
294                                     boolean required,
295                                     Object defaultValue,
296                                     List enumeratedValues)
297        {
298          super (owner, classType, false, defaultValue);
299          this.enumeratedValues = enumeratedValues;
300          valueType = IIOMetadataFormat.VALUE_ENUMERATION;
301        }
302    
303        public Object[] getEnumerations ()
304        {
305          return enumeratedValues.toArray();
306        }
307      }
308    
309      private class NodeObjectBounded extends NodeObject
310      {
311        protected Comparable minValue;
312        protected Comparable maxValue;
313        protected boolean minInclusive;
314        protected boolean maxInclusive;
315    
316        public NodeObjectBounded (Element owner,
317                                  Class classType,
318                                  Object defaultValue,
319                                  Comparable minValue,
320                                  Comparable maxValue,
321                                  boolean minInclusive,
322                                  boolean maxInclusive)
323        {
324          super (owner, classType, false, defaultValue);
325          this.minValue = minValue;
326          this.maxValue = maxValue;
327          this.minInclusive = minInclusive;
328          this.maxInclusive = maxInclusive;
329          if (minInclusive)
330            {
331              if (maxInclusive)
332                valueType = IIOMetadataFormat.VALUE_RANGE_MIN_MAX_INCLUSIVE;
333              else
334                valueType = IIOMetadataFormat.VALUE_RANGE_MIN_INCLUSIVE;
335            }
336          else
337            {
338              if (maxInclusive)
339                valueType = IIOMetadataFormat.VALUE_RANGE_MAX_INCLUSIVE;
340              else
341                valueType = IIOMetadataFormat.VALUE_RANGE;
342            }
343        }
344    
345        public Comparable getMinValue ()
346        {
347          return minValue;
348        }
349    
350        public Comparable getMaxValue ()
351        {
352          return maxValue;
353        }
354      }
355    
356      private class NodeObjectArray extends NodeObject
357      {
358        protected Integer arrayMinLength;
359        protected Integer arrayMaxLength;
360    
361        public NodeObjectArray (Element owner,
362                                Class classType,
363                                int arrayMinLength,
364                                int arrayMaxLength)
365        {
366          super (owner, classType, false, null);
367          this.arrayMinLength = new Integer (arrayMinLength);
368          this.arrayMaxLength = new Integer (arrayMaxLength);
369          valueType = IIOMetadataFormat.VALUE_LIST;
370        }
371    
372        public Comparable getArrayMinLength ()
373        {
374          return arrayMinLength;
375        }
376    
377        public Comparable getArrayMaxLength ()
378        {
379          return arrayMaxLength;
380        }
381      }
382    
383      /**
384       * Construct a blank IIOMetadataFormatImpl with the given root name
385       * and child policy.
386       *
387       * @param rootName the root element name
388       * @param childPolicy the child policy of the root element
389       *
390       * @exception IllegalArgumentException if rootName is null
391       * @exception IllegalArgumentException if childPolicy is
392       * CHILD_POLICY_REPEAT or if childPolicy is not a CHILD_POLICY
393       * constant
394       */
395      public IIOMetadataFormatImpl (String rootName, int childPolicy)
396      {
397        if (rootName == null)
398          throw new IllegalArgumentException ("null argument");
399    
400        if (childPolicy < IIOMetadataFormat.CHILD_POLICY_ALL
401            || childPolicy > IIOMetadataFormat.CHILD_POLICY_SOME
402            || childPolicy == IIOMetadataFormat.CHILD_POLICY_REPEAT)
403          throw new IllegalArgumentException ("wrong child policy");
404    
405        nodes.put (rootName, new IIOMetadataNode (rootName));
406        childPolicies.put (rootName, new Integer (childPolicy));
407        this.rootName = rootName;
408      }
409    
410      /**
411       * Construct a blank IIOMetadataFormatImpl with the given root name,
412       * a child policy of CHILD_POLICY_REPEAT and the given minimum and
413       * maximum limits on the number of root element children.
414       *
415       * @param rootName the root element name
416       * @param minChildren the minimum number of children that this node
417       * can have
418       * @param maxChildren the maximum number of children that this node
419       * can have
420       *
421       * @exception IllegalArgumentException if rootName is null
422       * @exception IllegalArgumentException if minChildren is less than
423       * zero or greater than maxChildren
424       */
425      public IIOMetadataFormatImpl (String rootName,
426                                    int minChildren,
427                                    int maxChildren)
428      {
429        if (rootName == null)
430          throw new IllegalArgumentException ("null argument");
431    
432        if (minChildren < 0 || maxChildren < minChildren)
433          throw new IllegalArgumentException ("invalid min or max children argument");
434    
435        nodes.put (rootName, new IIOMetadataNode (rootName));
436        childPolicies.put (rootName, new Integer (IIOMetadataFormat.CHILD_POLICY_REPEAT));
437        childRanges.put (rootName, new int [] { minChildren, maxChildren });
438        this.rootName = rootName;
439      }
440    
441      protected void addAttribute (String elementName,
442                                   String attrName,
443                                   int dataType,
444                                   boolean required,
445                                   String defaultValue)
446      {
447        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
448        node.setAttributeNode (new IIOMetadataNodeAttr (node,
449                                                        attrName,
450                                                        dataType,
451                                                        required,
452                                                        defaultValue));
453      }
454    
455      protected void addAttribute (String elementName,
456                                   String attrName,
457                                   int dataType,
458                                   boolean required,
459                                   String defaultValue,
460                                   List<String> enumeratedValues)
461      {
462        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
463        node.setAttributeNode (new IIOMetadataNodeAttrEnumerated (node,
464                                                                  attrName,
465                                                                  dataType,
466                                                                  required,
467                                                                  defaultValue,
468                                                                  enumeratedValues));
469      }
470    
471      protected void addAttribute (String elementName,
472                                   String attrName,
473                                   int dataType,
474                                   boolean required,
475                                   String defaultValue,
476                                   String minValue,
477                                   String maxValue,
478                                   boolean minInclusive,
479                                   boolean maxInclusive)
480      {
481        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
482        node.setAttributeNode (new IIOMetadataNodeAttrBounded (node,
483                                                               attrName,
484                                                               dataType,
485                                                               required,
486                                                               defaultValue,
487                                                               minValue,
488                                                               maxValue,
489                                                               minInclusive,
490                                                               maxInclusive));
491      }
492    
493      protected void addAttribute (String elementName,
494                                   String attrName,
495                                   int dataType,
496                                   boolean required,
497                                   int listMinLength,
498                                   int listMaxLength)
499      {
500        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
501        node.setAttributeNode (new IIOMetadataNodeAttrList (node,
502                                                            attrName,
503                                                            dataType,
504                                                            required,
505                                                            listMinLength,
506                                                            listMaxLength));
507      }
508    
509      protected void addBooleanAttribute (String elementName,
510                                          String attrName,
511                                          boolean hasDefaultValue,
512                                          boolean defaultValue)
513      {
514        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
515    
516        List enumeratedValues = new ArrayList();
517        enumeratedValues.add ("TRUE");
518        enumeratedValues.add ("FALSE");
519    
520        node.setAttributeNode (new IIOMetadataNodeAttrEnumerated (node,
521                                                                  attrName,
522                                                                  IIOMetadataFormat.DATATYPE_BOOLEAN,
523                                                                  hasDefaultValue,
524                                                                  defaultValue ? "TRUE" : "FALSE",
525                                                                  enumeratedValues));
526      }
527    
528      protected void addChildElement (String elementName, String parentName)
529      {
530        IIOMetadataNode node = (IIOMetadataNode) nodes.get (parentName);
531    
532        node.appendChild (new IIOMetadataNode (elementName));
533        childPolicies.put (elementName, new Integer (IIOMetadataFormat.CHILD_POLICY_REPEAT));
534      }
535    
536      protected void addElement (String elementName, String parentName, int childPolicy)
537      {
538        IIOMetadataNode node = (IIOMetadataNode) nodes.get (parentName);
539    
540        node.appendChild (new IIOMetadataNode (elementName));
541        childPolicies.put (elementName, new Integer (childPolicy));
542      }
543    
544      protected void addElement (String elementName, String parentName,
545                                 int minChildren, int maxChildren)
546      {
547        addChildElement (elementName, parentName);
548        childRanges.put (elementName, new int [] { minChildren, maxChildren });
549      }
550    
551      private void addNodeObject (IIOMetadataNode node, NodeObject o)
552      {
553        node.setUserObject (o);
554      }
555    
556      private NodeObject getNodeObject (IIOMetadataNode node)
557      {
558        return (NodeObject) node.getUserObject ();
559      }
560    
561      private void removeNodeObject (IIOMetadataNode node)
562      {
563        node.setUserObject (null);
564      }
565    
566      protected <T> void addObjectValue (String elementName, Class<T> classType,
567                                         boolean required, T defaultValue)
568      {
569        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
570        addNodeObject (node, new NodeObject (node,
571                                             classType,
572                                             required,
573                                             defaultValue));
574      }
575    
576      protected <T> void addObjectValue (String elementName, Class<T> classType,
577                                         boolean required, T defaultValue,
578                                         List<? extends T> enumeratedValues)
579      {
580        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
581        addNodeObject (node, new NodeObjectEnumerated (node,
582                                                       classType,
583                                                       required,
584                                                       defaultValue,
585                                                       enumeratedValues));
586      }
587    
588      protected <T extends Object & Comparable<? super T>>
589      void addObjectValue (String elementName, Class<T> classType,
590                           T defaultValue,
591                           Comparable<? super T> minValue,
592                           Comparable<? super T> maxValue,
593                           boolean minInclusive,
594                           boolean maxInclusive)
595      {
596        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
597        addNodeObject (node, new NodeObjectBounded (node,
598                                                    classType,
599                                                    defaultValue,
600                                                    minValue,
601                                                    maxValue,
602                                                    minInclusive,
603                                                    maxInclusive));
604      }
605    
606      protected void addObjectValue (String elementName, Class<?> classType,
607                                     int arrayMinLength, int arrayMaxLength)
608      {
609        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
610        addNodeObject (node, new NodeObjectArray (node,
611                                                  classType,
612                                                  arrayMinLength,
613                                                  arrayMaxLength));
614      }
615    
616      public String getRootName ()
617      {
618        return rootName;
619      }
620    
621      protected String getResourceBaseName ()
622      {
623        return resourceBaseName;
624      }
625    
626      public static IIOMetadataFormat getStandardFormatInstance ()
627      {
628        // FIXME: populate this with the standard metadata format
629        return new IIOMetadataFormatImpl (standardMetadataFormatName,
630                                          IIOMetadataFormat.CHILD_POLICY_ALL)
631          {
632            public boolean canNodeAppear (String elementName,
633                                          ImageTypeSpecifier specifier)
634            {
635              return true;
636            }
637          };
638      }
639    
640      public abstract boolean canNodeAppear (String elementName,
641                                             ImageTypeSpecifier specifier);
642    
643      protected void removeAttribute (String elementName,
644                                      String attrName)
645      {
646        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
647        node.removeAttribute (attrName);
648      }
649    
650      protected void removeElement (String elementName)
651      {
652        nodes.remove (elementName);
653      }
654    
655      protected void removeObjectValue (String elementName)
656      {
657        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
658        removeNodeObject (node);
659      }
660    
661      protected void setResourceBaseName (String resourceBaseName)
662      {
663        this.resourceBaseName = resourceBaseName;
664      }
665    
666      public int getAttributeDataType (String elementName, String attrName)
667      {
668        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
669        IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
670        return attr.getDataType ();
671      }
672    
673      public String getAttributeDefaultValue (String elementName, String attrName)
674      {
675        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
676        IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
677        return attr.getValue();
678      }
679    
680      public String getAttributeDescription (String elementName, String attrName, Locale locale)
681      {
682        return getDescription (elementName + "/" + attrName, locale);
683      }
684    
685      public String[] getAttributeEnumerations (String elementName, String attrName)
686      {
687        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
688        IIOMetadataNodeAttrEnumerated attr =
689          (IIOMetadataNodeAttrEnumerated) node.getAttributeNode (attrName);
690    
691        Object[] attrEnums = attr.getEnumerations();
692    
693        String[] attrNames = new String[attrEnums.length];
694    
695        for (int i = 0; i < attrEnums.length; i++)
696          {
697            attrNames[i] = (String) attrEnums[i];
698          }
699    
700        return attrNames;
701      }
702    
703      public int getAttributeListMaxLength (String elementName, String attrName)
704      {
705        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
706        IIOMetadataNodeAttrList attr =
707          (IIOMetadataNodeAttrList) node.getAttributeNode (attrName);
708        return attr.getListMaxLength();
709      }
710    
711      public int getAttributeListMinLength (String elementName, String attrName)
712      {
713        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
714        IIOMetadataNodeAttrList attr =
715          (IIOMetadataNodeAttrList) node.getAttributeNode (attrName);
716        return attr.getListMinLength();
717      }
718    
719      public String getAttributeMaxValue (String elementName, String attrName)
720      {
721        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
722        IIOMetadataNodeAttrBounded attr =
723          (IIOMetadataNodeAttrBounded) node.getAttributeNode (attrName);
724        return attr.getMaxValue();
725      }
726    
727      public String getAttributeMinValue (String elementName, String attrName)
728      {
729        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
730        IIOMetadataNodeAttrBounded attr =
731          (IIOMetadataNodeAttrBounded) node.getAttributeNode (attrName);
732        return attr.getMinValue();
733      }
734    
735      public String[] getAttributeNames (String elementName)
736      {
737        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
738    
739        NamedNodeMap attrNodes = node.getAttributes();
740    
741        String[] attrNames = new String[attrNodes.getLength()];
742    
743        for (int i = 0; i < attrNodes.getLength(); i++)
744          {
745            attrNames[i] = attrNodes.item (i).getLocalName();
746          }
747    
748        return attrNames;
749      }
750    
751      public int getAttributeValueType (String elementName, String attrName)
752      {
753        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
754        IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
755        return attr.getDataType();
756      }
757    
758      public String[] getChildNames (String elementName)
759      {
760        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
761    
762        NodeList childNodes = node.getChildNodes();
763    
764        String[] childNames = new String[childNodes.getLength()];
765    
766        for (int i = 0; i < childNodes.getLength(); i++)
767          {
768            childNames[i] = childNodes.item (i).getLocalName();
769          }
770    
771        return childNames;
772      }
773    
774      public int getChildPolicy (String elementName)
775      {
776        return ((Integer) childPolicies.get (elementName)).intValue();
777      }
778    
779      private String getDescription (String resourceName, Locale locale)
780      {
781        if (resourceBaseName == null)
782          return null;
783    
784        Locale l = locale;
785    
786        if (l == null)
787          l = Locale.getDefault();
788    
789        ResourceBundle bundle = ResourceBundle.getBundle (resourceBaseName, locale);
790    
791        String desc = null;
792    
793        if (bundle == null)
794          {
795            try
796              {
797                desc = bundle.getString (resourceName);
798              }
799            catch (MissingResourceException e)
800              {
801                desc = null;
802              }
803          }
804    
805        return desc;
806      }
807    
808      public String getElementDescription (String elementName, Locale locale)
809      {
810        return getDescription (elementName, locale);
811      }
812    
813      public int getElementMaxChildren (String elementName)
814      {
815        return ((int[]) childRanges.get (elementName))[1];
816      }
817    
818      public int getElementMinChildren (String elementName)
819      {
820        return ((int[]) childRanges.get (elementName))[0];
821      }
822    
823      public int getObjectArrayMaxLength (String elementName)
824      {
825        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
826        return ((Integer) ((NodeObjectArray) getNodeObject (node)).getArrayMaxLength ()).intValue();
827      }
828    
829      public int getObjectArrayMinLength (String elementName)
830      {
831        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
832        return ((Integer) ((NodeObjectArray) getNodeObject (node)).getArrayMinLength ()).intValue();
833      }
834    
835      public Class<?> getObjectClass (String elementName)
836      {
837        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
838        return getNodeObject (node).getClassType ();
839      }
840    
841      public Object getObjectDefaultValue (String elementName)
842      {
843        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
844        return getNodeObject (node).getDefaultValue ();
845      }
846    
847      public Object[] getObjectEnumerations (String elementName)
848      {
849        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
850        return ((NodeObjectEnumerated) getNodeObject (node)).getEnumerations ();
851      }
852    
853      public Comparable<?> getObjectMaxValue (String elementName)
854      {
855        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
856        return ((NodeObjectBounded) getNodeObject (node)).getMaxValue ();
857      }
858    
859      public Comparable<?> getObjectMinValue (String elementName)
860      {
861        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
862        return ((NodeObjectBounded) getNodeObject (node)).getMinValue ();
863      }
864    
865      public int getObjectValueType (String elementName)
866      {
867        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
868        NodeObject n = getNodeObject (node);
869    
870        if (n == null)
871          return IIOMetadataFormat.VALUE_NONE;
872        else
873          return n.getValueType ();
874      }
875    
876      public boolean isAttributeRequired (String elementName, String attrName)
877      {
878        IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
879        return ((IIOMetadataNodeAttr) node.getAttributeNode (attrName)).isRequired();
880      }
881    }