001 /* IIOMetadataNode.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 java.util.ArrayList;
042 import java.util.HashMap;
043 import java.util.Iterator;
044 import java.util.List;
045
046 import org.w3c.dom.Attr;
047 import org.w3c.dom.DOMException;
048 import org.w3c.dom.Document;
049 import org.w3c.dom.Element;
050 import org.w3c.dom.NamedNodeMap;
051 import org.w3c.dom.Node;
052 import org.w3c.dom.NodeList;
053 import org.w3c.dom.TypeInfo;
054 import org.w3c.dom.UserDataHandler;
055 import javax.imageio.metadata.IIOMetadataFormatImpl.IIOMetadataNodeAttr;
056
057 public class IIOMetadataNode
058 implements Element, NodeList
059 {
060 private String name;
061 private HashMap attrs = new HashMap();
062 private List children = new ArrayList();
063 private IIOMetadataNode parent;
064 private Object obj;
065
066 /**
067 * Simple NamedNodeMap class for IIOMetadataNode.
068 *
069 * @author jlquinn
070 */
071 private class IIONamedNodeMap implements NamedNodeMap
072 {
073 HashMap attrs;
074
075 /**
076 * @param attrs
077 * @param node
078 */
079 public IIONamedNodeMap(HashMap attrs)
080 {
081 this.attrs = attrs;
082 }
083
084 /* (non-Javadoc)
085 * @see org.w3c.dom.NamedNodeMap#getNamedItem(java.lang.String)
086 */
087 public Node getNamedItem(String name)
088 {
089 return (Node)attrs.get(name);
090 }
091
092 /* (non-Javadoc)
093 * @see org.w3c.dom.NamedNodeMap#setNamedItem(org.w3c.dom.Node)
094 */
095 public Node setNamedItem(Node arg) throws DOMException
096 {
097 if (arg instanceof IIOMetadataNodeAttr)
098 {
099 IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr) arg;
100 // The only code that can successfully do this is in this package.
101 if (attr.owner != null)
102 throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR, "");
103 return (Node)attrs.put(attr.name, attr);
104 }
105 // Anything else gets treated as an invalid op.
106 throw new DOMException(DOMException.HIERARCHY_REQUEST_ERR, "");
107 }
108
109 /* (non-Javadoc)
110 * @see org.w3c.dom.NamedNodeMap#removeNamedItem(java.lang.String)
111 */
112 public Node removeNamedItem(String name) throws DOMException
113 {
114 return (Node)attrs.remove(name);
115 }
116
117 /* (non-Javadoc)
118 * @see org.w3c.dom.NamedNodeMap#item(int)
119 */
120 public Node item(int index)
121 {
122 return (Node)attrs.values().toArray()[index];
123 }
124
125 /* (non-Javadoc)
126 * @see org.w3c.dom.NamedNodeMap#getLength()
127 */
128 public int getLength()
129 {
130 return attrs.size();
131 }
132
133 /* (non-Javadoc)
134 * @see org.w3c.dom.NamedNodeMap#getNamedItemNS(java.lang.String, java.lang.String)
135 */
136 public Node getNamedItemNS(String namespaceURI, String localName)
137 {
138 return getNamedItem(localName);
139 }
140
141 /* (non-Javadoc)
142 * @see org.w3c.dom.NamedNodeMap#setNamedItemNS(org.w3c.dom.Node)
143 */
144 public Node setNamedItemNS(Node arg) throws DOMException
145 {
146 return setNamedItem(arg);
147 }
148
149 /* (non-Javadoc)
150 * @see org.w3c.dom.NamedNodeMap#removeNamedItemNS(java.lang.String, java.lang.String)
151 */
152 public Node removeNamedItemNS(String namespaceURI, String localName)
153 throws DOMException
154 {
155 return removeNamedItem(localName);
156 }
157 }
158
159 /**
160 * Simple NodeList implementation for IIOMetadataNode.
161 *
162 * @author jlquinn
163 *
164 */
165 private class IIONodeList implements NodeList
166 {
167 List children = new ArrayList();
168
169 /* (non-Javadoc)
170 * @see org.w3c.dom.NodeList#item(int)
171 */
172 public Node item(int index)
173 {
174 return (index < children.size()) ? (Node)children.get(index) : null;
175 }
176
177 /* (non-Javadoc)
178 * @see org.w3c.dom.NodeList#getLength()
179 */
180 public int getLength()
181 {
182 return children.size();
183 }
184 }
185
186 public IIOMetadataNode()
187 {
188 // Do nothing here.
189 }
190
191 public IIOMetadataNode(String nodename)
192 {
193 name = nodename;
194 }
195
196 public Object getUserObject()
197 {
198 return obj;
199 }
200
201 public void setUserObject(Object o)
202 {
203 obj = o;
204 }
205
206 public short compareDocumentPosition(Node other)
207 throws DOMException
208 {
209 return Element.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC;
210 }
211
212 /* (non-Javadoc)
213 * @see org.w3c.dom.Element#getAttribute(java.lang.String)
214 */
215 public String getAttribute(String name)
216 {
217 Attr anode = (Attr) attrs.get(name);
218 return anode != null ? anode.getValue() : null;
219 }
220
221 /* (non-Javadoc)
222 * @see org.w3c.dom.Element#getAttributeNode(java.lang.String)
223 */
224 public Attr getAttributeNode(String name)
225 {
226 String val = getAttribute(name);
227 if (val != null)
228 return new IIOMetadataNodeAttr(this, name, val);
229 return null;
230 }
231
232 /* (non-Javadoc)
233 * @see org.w3c.dom.Element#getAttributeNodeNS(java.lang.String, java.lang.String)
234 */
235 public Attr getAttributeNodeNS(String namespaceURI, String localName)
236 {
237 return getAttributeNode(localName);
238 }
239
240 /* (non-Javadoc)
241 * @see org.w3c.dom.Element#getAttributeNS(java.lang.String, java.lang.String)
242 */
243 public String getAttributeNS(String namespaceURI, String localName)
244 {
245 return getAttribute(localName);
246 }
247
248 public String getBaseURI()
249 {
250 return null;
251 }
252
253 // Recursive function for assembling a node list.
254 private void getElementsRecurse(IIONodeList list, String name)
255 {
256 for (int i=0; i < children.size(); i++)
257 {
258 if (((Node)children.get(i)).getNodeName().equals(name))
259 list.children.add(children.get(i));
260 getElementsRecurse(list, name);
261 }
262 }
263
264 /* (non-Javadoc)
265 * @see org.w3c.dom.Element#getElementsByTagName(java.lang.String)
266 */
267 public NodeList getElementsByTagName(String name)
268 {
269 IIONodeList list = new IIONodeList();
270 getElementsRecurse(list, name);
271 return list;
272 }
273
274 /* (non-Javadoc)
275 * @see org.w3c.dom.Element#getElementsByTagNameNS(java.lang.String, java.lang.String)
276 */
277 public NodeList getElementsByTagNameNS(String namespaceURI, String localName)
278 {
279 IIONodeList list = new IIONodeList();
280 getElementsRecurse(list, name);
281 return list;
282 }
283
284 /* (non-Javadoc)
285 * @see org.w3c.dom.Element#getTagName()
286 */
287 public String getTagName()
288 {
289 return name;
290 }
291
292 /* (non-Javadoc)
293 * @see org.w3c.dom.Element#hasAttribute(java.lang.String)
294 */
295 public boolean hasAttribute(String name)
296 {
297 return attrs.containsKey(name);
298 }
299
300 /* (non-Javadoc)
301 * @see org.w3c.dom.Element#hasAttributeNS(java.lang.String, java.lang.String)
302 */
303 public boolean hasAttributeNS(String namespaceURI, String localName)
304 {
305 return attrs.containsKey(localName);
306 }
307
308 /* (non-Javadoc)
309 * @see org.w3c.dom.Element#removeAttribute(java.lang.String)
310 */
311 public void removeAttribute(String name)
312 {
313 attrs.remove(name);
314 }
315
316 /* (non-Javadoc)
317 * @see org.w3c.dom.Element#removeAttributeNode(org.w3c.dom.Attr)
318 */
319 public Attr removeAttributeNode(Attr oldAttr)
320 {
321 return (Attr)attrs.remove(oldAttr.getName());
322 }
323
324 /* (non-Javadoc)
325 * @see org.w3c.dom.Element#removeAttributeNS(java.lang.String, java.lang.String)
326 */
327 public void removeAttributeNS(String namespaceURI, String localName)
328 {
329 removeAttribute(localName);
330 }
331
332 /* (non-Javadoc)
333 * @see org.w3c.dom.Element#setAttribute(java.lang.String, java.lang.String)
334 */
335 public void setAttribute(String name, String value)
336 {
337 Attr attr = getAttributeNode(name);
338 if (attr != null)
339 attr.setValue(value);
340 else
341 attrs.put(name, new IIOMetadataNodeAttr(this, name, value));
342 }
343
344 /* (non-Javadoc)
345 * @see org.w3c.dom.Element#setAttributeNode(org.w3c.dom.Attr)
346 */
347 public Attr setAttributeNode(Attr newAttr)
348 {
349 return (Attr)attrs.put(newAttr.getName(), newAttr);
350 }
351
352 /* (non-Javadoc)
353 * @see org.w3c.dom.Element#setAttributeNodeNS(org.w3c.dom.Attr)
354 */
355 public Attr setAttributeNodeNS(Attr newAttr)
356 {
357 return (Attr)attrs.put(newAttr.getName(), newAttr);
358 }
359
360 /* (non-Javadoc)
361 * @see org.w3c.dom.Element#setAttributeNS(java.lang.String, java.lang.String, java.lang.String)
362 */
363 public void setAttributeNS(String namespaceURI, String qualifiedName, String value)
364 {
365 setAttribute(qualifiedName, value);
366 }
367
368 /* (non-Javadoc)
369 * @see org.w3c.dom.NodeList#getLength()
370 */
371 public int getLength()
372 {
373 return children.size();
374 }
375
376 /* (non-Javadoc)
377 * @see org.w3c.dom.NodeList#item(int)
378 */
379 public Node item(int index)
380 {
381 if (index < children.size())
382 return (Node)children.get(index);
383 else
384 return null;
385 }
386
387 /* (non-Javadoc)
388 * @see org.w3c.dom.Node#appendChild(org.w3c.dom.Node)
389 */
390 public Node appendChild(Node newChild)
391 {
392 if (newChild == null)
393 throw new IllegalArgumentException("Child node is null");
394
395 IIOMetadataNode child = (IIOMetadataNode) newChild;
396
397 children.add(child);
398 child.parent = this;
399 return this;
400 }
401
402 /* (non-Javadoc)
403 * @see org.w3c.dom.Node#cloneNode(boolean)
404 */
405 public Node cloneNode(boolean deep)
406 {
407 IIOMetadataNode newnode = new IIOMetadataNode(name);
408 newnode.parent = null;
409 newnode.obj = obj;
410 if (deep)
411 {
412 for (int i=0; i < children.size(); i++)
413 newnode.children.add(((Node)children.get(i)).cloneNode(deep));
414 }
415
416 // clone attrs
417 for (Iterator it = attrs.values().iterator(); it.hasNext();)
418 {
419 IIOMetadataNodeAttr attr = (IIOMetadataNodeAttr)it.next();
420 newnode.attrs.put(attr.name, attr.cloneNode(deep));
421 attr.owner = newnode;
422 }
423
424 return newnode;
425 }
426
427 /* (non-Javadoc)
428 * @see org.w3c.dom.Node#getAttributes()
429 */
430 public NamedNodeMap getAttributes()
431 {
432 return new IIONamedNodeMap(attrs);
433 }
434
435 /* (non-Javadoc)
436 * @see org.w3c.dom.Node#getChildNodes()
437 */
438 public NodeList getChildNodes()
439 {
440 return this;
441 }
442
443 public Object getFeature(String feature, String version)
444 {
445 return null;
446 }
447
448 /* (non-Javadoc)
449 * @see org.w3c.dom.Node#getFirstChild()
450 */
451 public Node getFirstChild()
452 {
453 return (children.size() > 0) ? (Node)children.get(0) : null;
454 }
455
456 /* (non-Javadoc)
457 * @see org.w3c.dom.Node#getLastChild()
458 */
459 public Node getLastChild()
460 {
461 return (children.size() > 0) ? (Node)children.get(children.size() - 1)
462 : null;
463 }
464
465 /* (non-Javadoc)
466 * @see org.w3c.dom.Node#getLocalName()
467 */
468 public String getLocalName()
469 {
470 return name;
471 }
472
473 /* (non-Javadoc)
474 * @see org.w3c.dom.Node#getNamespaceURI()
475 */
476 public String getNamespaceURI()
477 {
478 return null;
479 }
480
481 /* (non-Javadoc)
482 * @see org.w3c.dom.Node#getNextSibling()
483 */
484 public Node getNextSibling()
485 {
486 // If this op needs to be faster, add links to prev and next nodes.
487 if (parent == null) return null;
488 int idx = parent.children.indexOf(this);
489 return (idx == parent.children.size() - 1) ? null
490 : (Node)parent.children.get(idx + 1);
491 }
492
493 /* (non-Javadoc)
494 * @see org.w3c.dom.Node#getNodeName()
495 */
496 public String getNodeName()
497 {
498 return name;
499 }
500
501 /* (non-Javadoc)
502 * @see org.w3c.dom.Node#getNodeType()
503 */
504 public short getNodeType()
505 {
506 return ELEMENT_NODE;
507 }
508
509 /* (non-Javadoc)
510 * @see org.w3c.dom.Node#getNodeValue()
511 */
512 public String getNodeValue()
513 {
514 return null;
515 }
516
517 /* (non-Javadoc)
518 * @see org.w3c.dom.Node#getOwnerDocument()
519 */
520 public Document getOwnerDocument()
521 {
522 // IOMetadataNodes have no owner
523 return null;
524 }
525
526 /* (non-Javadoc)
527 * @see org.w3c.dom.Node#getParentNode()
528 */
529 public Node getParentNode()
530 {
531 return parent;
532 }
533
534 /* (non-Javadoc)
535 * @see org.w3c.dom.Node#getPrefix()
536 */
537 public String getPrefix()
538 {
539 return null;
540 }
541
542 /* (non-Javadoc)
543 * @see org.w3c.dom.Node#getPreviousSibling()
544 */
545 public Node getPreviousSibling()
546 {
547 // If this op needs to be faster, add links to prev and next nodes.
548 if (parent == null) return null;
549 int idx = parent.children.indexOf(this);
550 return (idx == 0) ? null
551 : (Node)parent.children.get(idx - 1);
552 }
553
554 public TypeInfo getSchemaTypeInfo()
555 {
556 return null;
557 }
558
559 public String getTextContent()
560 throws DOMException
561 {
562 return null;
563 }
564
565 public Object getUserData(String key)
566 {
567 return null;
568 }
569
570 /* (non-Javadoc)
571 * @see org.w3c.dom.Node#hasAttributes()
572 */
573 public boolean hasAttributes()
574 {
575 return !attrs.isEmpty();
576 }
577
578 /* (non-Javadoc)
579 * @see org.w3c.dom.Node#hasChildNodes()
580 */
581 public boolean hasChildNodes()
582 {
583 return !children.isEmpty();
584 }
585
586 /* (non-Javadoc)
587 * @see org.w3c.dom.Node#insertBefore(org.w3c.dom.Node, org.w3c.dom.Node)
588 */
589 public Node insertBefore(Node newChild, Node refChild)
590 {
591 if (newChild == null)
592 throw new IllegalArgumentException();
593
594 int idx = children.indexOf(refChild);
595 if (idx == -1)
596 children.add(newChild);
597 else
598 children.add(idx, newChild);
599 ((IIOMetadataNode)newChild).parent = this;
600
601 return newChild;
602 }
603
604 public boolean isDefaultNamespace(String namespaceURI)
605 {
606 return true;
607 }
608
609 public boolean isEqualNode(Node arg)
610 {
611 return true;
612 }
613
614 public boolean isSameNode(Node other)
615 {
616 return this == other;
617 }
618
619 /* (non-Javadoc)
620 * @see org.w3c.dom.Node#isSupported(java.lang.String, java.lang.String)
621 */
622 public boolean isSupported(String feature, String version)
623 {
624 // No DOM features are supported
625 return false;
626 }
627
628 public String lookupNamespaceURI(String prefix)
629 {
630 return null;
631 }
632
633 public String lookupPrefix(String namespaceURI)
634 {
635 return null;
636 }
637
638 /* (non-Javadoc)
639 * @see org.w3c.dom.Node#normalize()
640 */
641 public void normalize()
642 {
643 // No text nodes so no action
644 }
645
646 /* (non-Javadoc)
647 * @see org.w3c.dom.Node#removeChild(org.w3c.dom.Node)
648 */
649 public Node removeChild(Node oldChild)
650 {
651 if (oldChild == null)
652 throw new IllegalArgumentException();
653 children.remove(oldChild);
654 ((IIOMetadataNode)oldChild).parent = null;
655
656 return oldChild;
657 }
658
659 /* (non-Javadoc)
660 * @see org.w3c.dom.Node#replaceChild(org.w3c.dom.Node, org.w3c.dom.Node)
661 */
662 public Node replaceChild(Node newChild, Node oldChild)
663 {
664 if (newChild == null)
665 throw new IllegalArgumentException();
666 children.set(children.indexOf(oldChild), newChild);
667 ((IIOMetadataNode)oldChild).parent = null;
668 return oldChild;
669 }
670
671 public void setIdAttribute(String name, boolean isId)
672 throws DOMException
673 {
674 }
675
676 public void setIdAttributeNode(Attr idAttr, boolean isId)
677 throws DOMException
678 {
679 }
680
681 public void setIdAttributeNS(String namespaceURI, String localName, boolean isId)
682 throws DOMException
683 {
684 }
685
686 /* (non-Javadoc)
687 * @see org.w3c.dom.Node#setNodeValue(java.lang.String)
688 */
689 public void setNodeValue(String nodeValue) throws DOMException
690 {
691 }
692
693 /* (non-Javadoc)
694 * @see org.w3c.dom.Node#setPrefix(java.lang.String)
695 */
696 public void setPrefix(String prefix)
697 {
698 }
699
700 public void setTextContent(String textContent)
701 throws DOMException
702 {
703 }
704
705 public Object setUserData(String key, Object data, UserDataHandler handler)
706 {
707 return null;
708 }
709 }