001: /*
002: * @(#)LocalNameMap.java 1.2 04/12/06
003: *
004: * Copyright (c) 2003 Sun Microsystems, Inc. All Rights Reserved.
005: *
006: * See the file "LICENSE.txt" for information on usage and redistribution
007: * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
008: */
009: package pnuts.xml;
010:
011: import java.util.Map;
012: import java.util.List;
013: import java.util.Set;
014: import java.util.HashMap;
015: import java.util.ArrayList;
016: import java.util.Iterator;
017: import java.util.Collection;
018: import java.util.AbstractCollection;
019: import java.util.NoSuchElementException;
020: import org.xml.sax.Attributes;
021:
022: /*
023: * A read-only Map object that consists of {localName->value} mappings of a Attributes object.
024: * entrySet()/keySet()/valueSet() conserve the order of the attributes.
025: *
026: * Since Attributes object is mutable, an instance of this class is also mutable. That is,
027: * the state of an AttributeMap object is changing during XML parsing.
028: */
029: class LocalNameMap extends SAXAttributeMap {
030: HashMap map;
031: ArrayList entries;
032:
033: void setAttributes(Attributes attributes) {
034: super .setAttributes(attributes);
035: this .map = null;
036: this .entries = null;
037: }
038:
039: public int size() {
040: if (map == null) {
041: return attributes.getLength();
042: } else {
043: return map.size();
044: }
045: }
046:
047: public Object get(Object key) {
048: if (map == null) {
049: prepareLocalNameMap();
050: }
051: return map.get(key);
052: }
053:
054: private void prepareLocalNameMap() {
055: entries = new ArrayList();
056: map = new HashMap();
057: for (int i = 0; i < attributes.getLength(); i++) {
058: String name = attributes.getLocalName(i);
059: String value = attributes.getValue(i);
060: entries.add(new Entry(name, value));
061: map.put(name, value);
062: }
063: }
064:
065: public Set keySet() {
066: if (entries == null) {
067: prepareLocalNameMap();
068: }
069: return new KeySet();
070: }
071:
072: public Collection values() {
073: if (entries == null) {
074: prepareLocalNameMap();
075: }
076: return new ValueSet();
077: }
078:
079: public Set entrySet() {
080: if (entries == null) {
081: prepareLocalNameMap();
082: }
083: return new EntrySet();
084: }
085:
086: static class Entry implements Map.Entry {
087: Object key;
088: Object value;
089:
090: Entry(Object key, Object value) {
091: this .key = key;
092: this .value = value;
093: }
094:
095: public Object getKey() {
096: return key;
097: }
098:
099: public Object getValue() {
100: return value;
101: }
102:
103: public Object setValue(Object value) {
104: throw new UnsupportedOperationException();
105: }
106: }
107:
108: class EntrySet extends AbstractCollection implements Set {
109: public int size() {
110: return entries.size();
111: }
112:
113: public boolean isEmpty() {
114: return entries.isEmpty();
115: }
116:
117: public Iterator iterator() {
118: return new EntrySetIterator();
119: }
120: }
121:
122: class ValueSet extends EntrySet {
123: public Iterator iterator() {
124: return new ValueSetIterator();
125: }
126: }
127:
128: class KeySet extends EntrySet {
129: public Iterator iterator() {
130: return new KeySetIterator();
131: }
132: }
133:
134: class EntrySetIterator implements Iterator {
135: private int max;
136: private int pos;
137:
138: EntrySetIterator() {
139: this .max = entries.size();
140: this .pos = 0;
141: }
142:
143: public boolean hasNext() {
144: return pos <= max - 1;
145: }
146:
147: protected Object get(int idx) {
148: return entries.get(idx);
149: }
150:
151: public Object next() {
152: if (pos > max - 1) {
153: throw new NoSuchElementException();
154: }
155: return get(pos++);
156: }
157:
158: public void remove() {
159: throw new UnsupportedOperationException();
160: }
161: }
162:
163: class ValueSetIterator extends EntrySetIterator {
164: protected Object get(int idx) {
165: return ((Map.Entry) entries.get(idx)).getValue();
166: }
167: }
168:
169: class KeySetIterator extends EntrySetIterator {
170: protected Object get(int idx) {
171: return ((Map.Entry) entries.get(idx)).getKey();
172: }
173: }
174: }
|