1 /* IIOMetadataFormatImpl.java --
2    Copyright (C) 2004  Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 
39 package javax.imageio.metadata;
40 
41 import org.w3c.dom.Attr;
42 import org.w3c.dom.Element;
43 import org.w3c.dom.NamedNodeMap;
44 import org.w3c.dom.NodeList;
45 import org.w3c.dom.TypeInfo;
46 import java.util.ArrayList;
47 import java.util.HashMap;
48 import java.util.Map;
49 import java.util.List;
50 import java.util.Locale;
51 import java.util.ResourceBundle;
52 import java.util.MissingResourceException;
53 import javax.imageio.ImageTypeSpecifier;
54 
55 public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat
56 {
57   /**
58    * The standard metadata format name constant set to
59    * "javax_imageio_1.0".
60    */
61   public static final String standardMetadataFormatName = "javax_imageio_1.0";
62 
63   private String rootName;
64 
65   // These maps assume that each element name is unique.
66 
67   private Map nodes = new HashMap();
68 
69   // A mapping from element name to child policy.
70   private Map childPolicies = new HashMap();
71 
72   // A mapping from element name to the permissible number of
73   // children.  Values in this map are length-two integer arrays; the
74   // first index is the minimum bound, the second index is the maximum
75   // bound.
76   private Map childRanges = new HashMap();
77 
78   private String resourceBaseName;
79 
80   // Package-private so that it may be used in IIOMetadataNode.
81   static class IIOMetadataNodeAttr extends IIOMetadataNode
82     implements Attr
83   {
84     protected Element owner;
85     protected String name;
86     protected int dataType;
87     protected boolean required;
88     protected String defaultValue;
89 
IIOMetadataNodeAttr(Element owner, String name, String defaultValue)90     public IIOMetadataNodeAttr (Element owner,
91                                 String name,
92                                 String defaultValue)
93     {
94       this (owner, name, IIOMetadataFormat.DATATYPE_STRING,
95             true, defaultValue);
96     }
97 
IIOMetadataNodeAttr(Element owner, String name, int dataType, boolean required, String defaultValue)98     public IIOMetadataNodeAttr (Element owner,
99                                 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 
getName()111     public String getName ()
112     {
113       return name;
114     }
115 
getOwnerElement()116     public Element getOwnerElement ()
117     {
118       return owner;
119     }
120 
getDataType()121     public int getDataType ()
122     {
123       return dataType;
124     }
125 
getSchemaTypeInfo()126     public TypeInfo getSchemaTypeInfo ()
127     {
128       return null;
129     }
130 
getSpecified()131     public boolean getSpecified ()
132     {
133       return false;
134     }
135 
getValue()136     public String getValue ()
137     {
138       return defaultValue;
139     }
140 
isId()141     public boolean isId()
142     {
143       return false;
144     }
145 
setValue(String value)146     public void setValue (String value)
147     {
148     }
149 
150     // new methods
151 
isRequired()152     public boolean isRequired ()
153     {
154       return required;
155     }
156   }
157 
158   private class IIOMetadataNodeAttrEnumerated extends IIOMetadataNodeAttr
159   {
160     protected List enumeratedValues;
161 
IIOMetadataNodeAttrEnumerated(Element owner, String name, int dataType, boolean required, String defaultValue, List enumeratedValues)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 
getEnumerations()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 
IIOMetadataNodeAttrBounded(Element owner, String name, int dataType, boolean required, String defaultValue, String minValue, String maxValue, boolean minInclusive, boolean maxInclusive)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 
getMinValue()203     public String getMinValue ()
204     {
205       return minValue;
206     }
207 
getMaxValue()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 
IIOMetadataNodeAttrList(Element owner, String name, int dataType, boolean required, int listMinLength, int listMaxLength)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 
getListMinLength()231     public int getListMinLength ()
232     {
233       return listMinLength;
234     }
235 
getListMaxLength()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 
NodeObject(Element owner, Class classType, boolean required, Object defaultValue)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 
getValueType()262     public int getValueType ()
263     {
264       return valueType;
265     }
266 
getClassType()267     public Class getClassType ()
268     {
269       return classType;
270     }
271 
getOwnerElement()272     public Element getOwnerElement ()
273     {
274       return owner;
275     }
276 
getDefaultValue()277     public Object getDefaultValue ()
278     {
279       return defaultValue;
280     }
281 
isRequired()282     public boolean isRequired ()
283     {
284       return required;
285     }
286   }
287 
288   private class NodeObjectEnumerated extends NodeObject
289   {
290     protected List enumeratedValues;
291 
NodeObjectEnumerated(Element owner, Class classType, boolean required, Object defaultValue, List enumeratedValues)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 
getEnumerations()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 
NodeObjectBounded(Element owner, Class classType, Object defaultValue, Comparable minValue, Comparable maxValue, boolean minInclusive, boolean maxInclusive)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 
getMinValue()345     public Comparable getMinValue ()
346     {
347       return minValue;
348     }
349 
getMaxValue()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 
NodeObjectArray(Element owner, Class classType, int arrayMinLength, int arrayMaxLength)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 
getArrayMinLength()372     public Comparable getArrayMinLength ()
373     {
374       return arrayMinLength;
375     }
376 
getArrayMaxLength()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    */
IIOMetadataFormatImpl(String rootName, int childPolicy)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    */
IIOMetadataFormatImpl(String rootName, int minChildren, int maxChildren)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 
addAttribute(String elementName, String attrName, int dataType, boolean required, String defaultValue)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 
addAttribute(String elementName, String attrName, int dataType, boolean required, String defaultValue, List<String> enumeratedValues)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 
addAttribute(String elementName, String attrName, int dataType, boolean required, String defaultValue, String minValue, String maxValue, boolean minInclusive, boolean maxInclusive)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 
addAttribute(String elementName, String attrName, int dataType, boolean required, int listMinLength, int listMaxLength)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 
addBooleanAttribute(String elementName, String attrName, boolean hasDefaultValue, boolean defaultValue)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 
addChildElement(String elementName, String parentName)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 
addElement(String elementName, String parentName, int childPolicy)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 
addElement(String elementName, String parentName, int minChildren, int maxChildren)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 
addNodeObject(IIOMetadataNode node, NodeObject o)551   private void addNodeObject (IIOMetadataNode node, NodeObject o)
552   {
553     node.setUserObject (o);
554   }
555 
getNodeObject(IIOMetadataNode node)556   private NodeObject getNodeObject (IIOMetadataNode node)
557   {
558     return (NodeObject) node.getUserObject ();
559   }
560 
removeNodeObject(IIOMetadataNode node)561   private void removeNodeObject (IIOMetadataNode node)
562   {
563     node.setUserObject (null);
564   }
565 
addObjectValue(String elementName, Class<T> classType, boolean required, T defaultValue)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 
addObjectValue(String elementName, Class<T> classType, boolean required, T defaultValue, List<? extends T> enumeratedValues)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>>
addObjectValue(String elementName, Class<T> classType, T defaultValue, Comparable<? super T> minValue, Comparable<? super T> maxValue, boolean minInclusive, boolean maxInclusive)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 
addObjectValue(String elementName, Class<?> classType, int arrayMinLength, int arrayMaxLength)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 
getRootName()616   public String getRootName ()
617   {
618     return rootName;
619   }
620 
getResourceBaseName()621   protected String getResourceBaseName ()
622   {
623     return resourceBaseName;
624   }
625 
getStandardFormatInstance()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 }
882