1 /* IIOMetadataFormatImpl.java --
2 Copyright (C) 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
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)
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.
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
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
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. */
39 package javax.imageio.metadata;
41 import org.w3c.dom.Attr;
42 import org.w3c.dom.DOMException;
43 import org.w3c.dom.Document;
44 import org.w3c.dom.Element;
45 import org.w3c.dom.NamedNodeMap;
46 import org.w3c.dom.Node;
47 import org.w3c.dom.NodeList;
48 import org.w3c.dom.TypeInfo;
49 import org.w3c.dom.UserDataHandler;
50 import java.util.ArrayList;
51 import java.util.HashMap;
53 import java.util.Iterator;
54 import java.util.List;
55 import java.util.Locale;
56 import java.util.ResourceBundle;
57 import java.util.MissingResourceException;
58 import javax.imageio.ImageTypeSpecifier;
60 public abstract class IIOMetadataFormatImpl implements IIOMetadataFormat
63 * The standard metadata format name constant set to
64 * "javax_imageio_1.0".
66 public static final String standardMetadataFormatName = "javax_imageio_1.0";
68 private String rootName;
70 // These maps assume that each element name is unique.
72 private Map nodes = new HashMap();
74 // A mapping from element name to child policy.
75 private Map childPolicies = new HashMap();
77 // A mapping from element name to the permissible number of
78 // children. Values in this map are length-two integer arrays; the
79 // first index is the minimum bound, the second index is the maximum
81 private Map childRanges = new HashMap();
83 private String resourceBaseName;
85 // Package-private so that it may be used in IIOMetadataNode.
86 static class IIOMetadataNodeAttr extends IIOMetadataNode
89 protected Element owner;
90 protected String name;
91 protected int dataType;
92 protected boolean required;
93 protected String defaultValue;
95 public IIOMetadataNodeAttr (Element owner,
99 this (owner, name, IIOMetadataFormat.DATATYPE_STRING,
103 public IIOMetadataNodeAttr (Element owner,
111 this.dataType = dataType;
112 this.required = required;
113 this.defaultValue = defaultValue;
116 public String getName ()
121 public Element getOwnerElement ()
126 public int getDataType ()
131 public TypeInfo getSchemaTypeInfo ()
136 public boolean getSpecified ()
141 public String getValue ()
146 public boolean isId()
151 public void setValue (String value)
157 public boolean isRequired ()
163 private class IIOMetadataNodeAttrEnumerated extends IIOMetadataNodeAttr
165 protected List enumeratedValues;
167 public IIOMetadataNodeAttrEnumerated (Element owner,
172 List enumeratedValues)
174 super (owner, name, dataType, required, defaultValue);
175 this.enumeratedValues = new ArrayList (enumeratedValues);
178 public Object[] getEnumerations ()
180 return enumeratedValues.toArray ();
184 private class IIOMetadataNodeAttrBounded extends IIOMetadataNodeAttr
186 protected String minValue;
187 protected String maxValue;
188 protected boolean minInclusive;
189 protected boolean maxInclusive;
191 public IIOMetadataNodeAttrBounded (Element owner,
198 boolean minInclusive,
199 boolean maxInclusive)
201 super (owner, name, dataType, required, defaultValue);
202 this.minValue = minValue;
203 this.maxValue = maxValue;
204 this.minInclusive = minInclusive;
205 this.maxInclusive = maxInclusive;
208 public String getMinValue ()
213 public String getMaxValue ()
219 private class IIOMetadataNodeAttrList extends IIOMetadataNodeAttr
221 protected int listMinLength;
222 protected int listMaxLength;
224 public IIOMetadataNodeAttrList (Element owner,
231 super (owner, name, dataType, required, null);
232 this.listMinLength = listMinLength;
233 this.listMaxLength = listMaxLength;
236 public int getListMinLength ()
238 return listMinLength;
241 public int getListMaxLength ()
243 return listMaxLength;
247 private class NodeObject
249 protected Element owner;
250 protected Class classType;
251 protected boolean required;
252 protected Object defaultValue;
253 protected int valueType;
255 public NodeObject (Element owner,
261 this.classType = classType;
262 this.required = required;
263 this.defaultValue = defaultValue;
264 valueType = IIOMetadataFormat.VALUE_ARBITRARY;
267 public int getValueType ()
272 public Class getClassType ()
277 public Element getOwnerElement ()
282 public Object getDefaultValue ()
287 public boolean isRequired ()
293 private class NodeObjectEnumerated extends NodeObject
295 protected List enumeratedValues;
297 public NodeObjectEnumerated (Element owner,
301 List enumeratedValues)
303 super (owner, classType, false, defaultValue);
304 this.enumeratedValues = enumeratedValues;
305 valueType = IIOMetadataFormat.VALUE_ENUMERATION;
308 public Object[] getEnumerations ()
310 return enumeratedValues.toArray();
314 private class NodeObjectBounded extends NodeObject
316 protected Comparable minValue;
317 protected Comparable maxValue;
318 protected boolean minInclusive;
319 protected boolean maxInclusive;
321 public NodeObjectBounded (Element owner,
326 boolean minInclusive,
327 boolean maxInclusive)
329 super (owner, classType, false, defaultValue);
330 this.minValue = minValue;
331 this.maxValue = maxValue;
332 this.minInclusive = minInclusive;
333 this.maxInclusive = maxInclusive;
337 valueType = IIOMetadataFormat.VALUE_RANGE_MIN_MAX_INCLUSIVE;
339 valueType = IIOMetadataFormat.VALUE_RANGE_MIN_INCLUSIVE;
344 valueType = IIOMetadataFormat.VALUE_RANGE_MAX_INCLUSIVE;
346 valueType = IIOMetadataFormat.VALUE_RANGE;
350 public Comparable getMinValue ()
355 public Comparable getMaxValue ()
361 private class NodeObjectArray extends NodeObject
363 protected Integer arrayMinLength;
364 protected Integer arrayMaxLength;
366 public NodeObjectArray (Element owner,
371 super (owner, classType, false, null);
372 this.arrayMinLength = new Integer (arrayMinLength);
373 this.arrayMaxLength = new Integer (arrayMaxLength);
374 valueType = IIOMetadataFormat.VALUE_LIST;
377 public Comparable getArrayMinLength ()
379 return arrayMinLength;
382 public Comparable getArrayMaxLength ()
384 return arrayMaxLength;
389 * Construct a blank IIOMetadataFormatImpl with the given root name
392 * @param rootName the root element name
393 * @param childPolicy the child policy of the root element
395 * @exception IllegalArgumentException if rootName is null
396 * @exception IllegalArgumentException if childPolicy is
397 * CHILD_POLICY_REPEAT or if childPolicy is not a CHILD_POLICY
400 public IIOMetadataFormatImpl (String rootName, int childPolicy)
402 if (rootName == null)
403 throw new IllegalArgumentException ("null argument");
405 if (childPolicy < IIOMetadataFormat.CHILD_POLICY_ALL
406 || childPolicy > IIOMetadataFormat.CHILD_POLICY_SOME
407 || childPolicy == IIOMetadataFormat.CHILD_POLICY_REPEAT)
408 throw new IllegalArgumentException ("wrong child policy");
410 nodes.put (rootName, new IIOMetadataNode (rootName));
411 childPolicies.put (rootName, new Integer (childPolicy));
412 this.rootName = rootName;
416 * Construct a blank IIOMetadataFormatImpl with the given root name,
417 * a child policy of CHILD_POLICY_REPEAT and the given minimum and
418 * maximum limits on the number of root element children.
420 * @param rootName the root element name
421 * @param minChildren the minimum number of children that this node
423 * @param maxChildren the maximum number of children that this node
426 * @exception IllegalArgumentException if rootName is null
427 * @exception IllegalArgumentException if minChildren is less than
428 * zero or greater than maxChildren
430 public IIOMetadataFormatImpl (String rootName,
434 if (rootName == null)
435 throw new IllegalArgumentException ("null argument");
437 if (minChildren < 0 || maxChildren < minChildren)
438 throw new IllegalArgumentException ("invalid min or max children argument");
440 nodes.put (rootName, new IIOMetadataNode (rootName));
441 childPolicies.put (rootName, new Integer (IIOMetadataFormat.CHILD_POLICY_REPEAT));
442 childRanges.put (rootName, new int [] { minChildren, maxChildren });
443 this.rootName = rootName;
446 protected void addAttribute (String elementName,
452 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
453 node.setAttributeNode (new IIOMetadataNodeAttr (node,
460 protected void addAttribute (String elementName,
465 List<String> enumeratedValues)
467 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
468 node.setAttributeNode (new IIOMetadataNodeAttrEnumerated (node,
476 protected void addAttribute (String elementName,
483 boolean minInclusive,
484 boolean maxInclusive)
486 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
487 node.setAttributeNode (new IIOMetadataNodeAttrBounded (node,
498 protected void addAttribute (String elementName,
505 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
506 node.setAttributeNode (new IIOMetadataNodeAttrList (node,
514 protected void addBooleanAttribute (String elementName,
516 boolean hasDefaultValue,
517 boolean defaultValue)
519 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
521 List enumeratedValues = new ArrayList();
522 enumeratedValues.add ("TRUE");
523 enumeratedValues.add ("FALSE");
525 node.setAttributeNode (new IIOMetadataNodeAttrEnumerated (node,
527 IIOMetadataFormat.DATATYPE_BOOLEAN,
529 defaultValue ? "TRUE" : "FALSE",
533 protected void addChildElement (String elementName, String parentName)
535 IIOMetadataNode node = (IIOMetadataNode) nodes.get (parentName);
537 node.appendChild (new IIOMetadataNode (elementName));
538 childPolicies.put (elementName, new Integer (IIOMetadataFormat.CHILD_POLICY_REPEAT));
541 protected void addElement (String elementName, String parentName, int childPolicy)
543 IIOMetadataNode node = (IIOMetadataNode) nodes.get (parentName);
545 node.appendChild (new IIOMetadataNode (elementName));
546 childPolicies.put (elementName, new Integer (childPolicy));
549 protected void addElement (String elementName, String parentName,
550 int minChildren, int maxChildren)
552 addChildElement (elementName, parentName);
553 childRanges.put (elementName, new int [] { minChildren, maxChildren });
556 private void addNodeObject (IIOMetadataNode node, NodeObject o)
558 node.setUserObject (o);
561 private NodeObject getNodeObject (IIOMetadataNode node)
563 return (NodeObject) node.getUserObject ();
566 private void removeNodeObject (IIOMetadataNode node)
568 node.setUserObject (null);
571 protected <T> void addObjectValue (String elementName, Class<T> classType,
572 boolean required, T defaultValue)
574 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
575 addNodeObject (node, new NodeObject (node,
581 protected <T> void addObjectValue (String elementName, Class<T> classType,
582 boolean required, T defaultValue,
583 List<? extends T> enumeratedValues)
585 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
586 addNodeObject (node, new NodeObjectEnumerated (node,
593 protected <T extends Object & Comparable<? super T>>
594 void addObjectValue (String elementName, Class<T> classType,
596 Comparable<? super T> minValue,
597 Comparable<? super T> maxValue,
598 boolean minInclusive,
599 boolean maxInclusive)
601 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
602 addNodeObject (node, new NodeObjectBounded (node,
611 protected void addObjectValue (String elementName, Class<?> classType,
612 int arrayMinLength, int arrayMaxLength)
614 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
615 addNodeObject (node, new NodeObjectArray (node,
621 public String getRootName ()
626 protected String getResourceBaseName ()
628 return resourceBaseName;
631 public static IIOMetadataFormat getStandardFormatInstance ()
633 // FIXME: populate this with the standard metadata format
634 return new IIOMetadataFormatImpl (standardMetadataFormatName,
635 IIOMetadataFormat.CHILD_POLICY_ALL)
637 public boolean canNodeAppear (String elementName,
638 ImageTypeSpecifier specifier)
645 public abstract boolean canNodeAppear (String elementName,
646 ImageTypeSpecifier specifier);
648 protected void removeAttribute (String elementName,
651 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
652 node.removeAttribute (attrName);
655 protected void removeElement (String elementName)
657 nodes.remove (elementName);
660 protected void removeObjectValue (String elementName)
662 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
663 removeNodeObject (node);
666 protected void setResourceBaseName (String resourceBaseName)
668 this.resourceBaseName = resourceBaseName;
671 public int getAttributeDataType (String elementName, String attrName)
673 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
674 IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
675 return attr.getDataType ();
678 public String getAttributeDefaultValue (String elementName, String attrName)
680 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
681 IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
682 return attr.getValue();
685 public String getAttributeDescription (String elementName, String attrName, Locale locale)
687 return getDescription (elementName + "/" + attrName, locale);
690 public String[] getAttributeEnumerations (String elementName, String attrName)
692 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
693 IIOMetadataNodeAttrEnumerated attr =
694 (IIOMetadataNodeAttrEnumerated) node.getAttributeNode (attrName);
696 Object[] attrEnums = attr.getEnumerations();
698 String[] attrNames = new String[attrEnums.length];
700 for (int i = 0; i < attrEnums.length; i++)
702 attrNames[i] = (String) attrEnums[i];
708 public int getAttributeListMaxLength (String elementName, String attrName)
710 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
711 IIOMetadataNodeAttrList attr =
712 (IIOMetadataNodeAttrList) node.getAttributeNode (attrName);
713 return attr.getListMaxLength();
716 public int getAttributeListMinLength (String elementName, String attrName)
718 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
719 IIOMetadataNodeAttrList attr =
720 (IIOMetadataNodeAttrList) node.getAttributeNode (attrName);
721 return attr.getListMinLength();
724 public String getAttributeMaxValue (String elementName, String attrName)
726 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
727 IIOMetadataNodeAttrBounded attr =
728 (IIOMetadataNodeAttrBounded) node.getAttributeNode (attrName);
729 return attr.getMaxValue();
732 public String getAttributeMinValue (String elementName, String attrName)
734 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
735 IIOMetadataNodeAttrBounded attr =
736 (IIOMetadataNodeAttrBounded) node.getAttributeNode (attrName);
737 return attr.getMinValue();
740 public String[] getAttributeNames (String elementName)
742 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
744 NamedNodeMap attrNodes = node.getAttributes();
746 String[] attrNames = new String[attrNodes.getLength()];
748 for (int i = 0; i < attrNodes.getLength(); i++)
750 attrNames[i] = attrNodes.item (i).getLocalName();
756 public int getAttributeValueType (String elementName, String attrName)
758 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
759 IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) node.getAttributeNode (attrName);
760 return attr.getDataType();
763 public String[] getChildNames (String elementName)
765 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
767 NodeList childNodes = node.getChildNodes();
769 String[] childNames = new String[childNodes.getLength()];
771 for (int i = 0; i < childNodes.getLength(); i++)
773 childNames[i] = childNodes.item (i).getLocalName();
779 public int getChildPolicy (String elementName)
781 return ((Integer) childPolicies.get (elementName)).intValue();
784 private String getDescription (String resourceName, Locale locale)
786 if (resourceBaseName == null)
792 l = Locale.getDefault();
794 ResourceBundle bundle = ResourceBundle.getBundle (resourceBaseName, locale);
802 desc = bundle.getString (resourceName);
804 catch (MissingResourceException e)
813 public String getElementDescription (String elementName, Locale locale)
815 return getDescription (elementName, locale);
818 public int getElementMaxChildren (String elementName)
820 return ((int[]) childRanges.get (elementName))[1];
823 public int getElementMinChildren (String elementName)
825 return ((int[]) childRanges.get (elementName))[0];
828 public int getObjectArrayMaxLength (String elementName)
830 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
831 return ((Integer) ((NodeObjectArray) getNodeObject (node)).getArrayMaxLength ()).intValue();
834 public int getObjectArrayMinLength (String elementName)
836 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
837 return ((Integer) ((NodeObjectArray) getNodeObject (node)).getArrayMinLength ()).intValue();
840 public Class<?> getObjectClass (String elementName)
842 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
843 return getNodeObject (node).getClassType ();
846 public Object getObjectDefaultValue (String elementName)
848 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
849 return getNodeObject (node).getDefaultValue ();
852 public Object[] getObjectEnumerations (String elementName)
854 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
855 return ((NodeObjectEnumerated) getNodeObject (node)).getEnumerations ();
858 public Comparable<?> getObjectMaxValue (String elementName)
860 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
861 return ((NodeObjectBounded) getNodeObject (node)).getMaxValue ();
864 public Comparable<?> getObjectMinValue (String elementName)
866 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
867 return ((NodeObjectBounded) getNodeObject (node)).getMinValue ();
870 public int getObjectValueType (String elementName)
872 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
873 NodeObject n = getNodeObject (node);
876 return IIOMetadataFormat.VALUE_NONE;
878 return n.getValueType ();
881 public boolean isAttributeRequired (String elementName, String attrName)
883 IIOMetadataNode node = (IIOMetadataNode) nodes.get (elementName);
884 return ((IIOMetadataNodeAttr) node.getAttributeNode (attrName)).isRequired();