001: /*
002: * Copyright (C) 2006 Joe Walnes.
003: * Copyright (C) 2006, 2007 XStream Committers.
004: * All rights reserved.
005: *
006: * The software in this package is published under the terms of the BSD
007: * style license a copy of which has been included with this distribution in
008: * the LICENSE.txt file.
009: *
010: * Created on 04. June 2006 by Joe Walnes
011: */
012: package com.thoughtworks.xstream.io.binary;
013:
014: import java.util.List;
015: import java.util.ArrayList;
016: import java.util.Iterator;
017: import java.util.Collections;
018:
019: /**
020: * Maintains the state of a pull reader at various states in the document depth.
021: *
022: * Used by the {@link BinaryStreamReader}
023: *
024: * @author Joe Walnes
025: * @since 1.2
026: */
027: class ReaderDepthState {
028:
029: private static final String EMPTY_STRING = "";
030:
031: private static class State {
032: String name;
033: String value;
034: List attributes;
035: boolean hasMoreChildren;
036: State parent;
037: }
038:
039: private static class Attribute {
040: String name;
041: String value;
042: }
043:
044: private State current;
045:
046: public void push() {
047: State newState = new State();
048: newState.parent = current;
049: current = newState;
050: }
051:
052: public void pop() {
053: current = current.parent;
054: }
055:
056: public String getName() {
057: return current.name;
058: }
059:
060: public void setName(String name) {
061: current.name = name;
062: }
063:
064: public String getValue() {
065: return current.value == null ? EMPTY_STRING : current.value;
066: }
067:
068: public void setValue(String value) {
069: current.value = value;
070: }
071:
072: public boolean hasMoreChildren() {
073: return current.hasMoreChildren;
074: }
075:
076: public void setHasMoreChildren(boolean hasMoreChildren) {
077: current.hasMoreChildren = hasMoreChildren;
078: }
079:
080: public void addAttribute(String name, String value) {
081: Attribute attribute = new Attribute();
082: attribute.name = name;
083: attribute.value = value;
084: if (current.attributes == null) {
085: current.attributes = new ArrayList();
086: }
087: current.attributes.add(attribute);
088: }
089:
090: public String getAttribute(String name) {
091: if (current.attributes == null) {
092: return null;
093: } else {
094: // For short maps, it's faster to iterate then do a hashlookup.
095: for (Iterator iterator = current.attributes.iterator(); iterator
096: .hasNext();) {
097: Attribute attribute = (Attribute) iterator.next();
098: if (attribute.name.equals(name)) {
099: return attribute.value;
100: }
101: }
102: return null;
103: }
104: }
105:
106: public String getAttribute(int index) {
107: if (current.attributes == null) {
108: return null;
109: } else {
110: Attribute attribute = (Attribute) current.attributes
111: .get(index);
112: return attribute.value;
113: }
114: }
115:
116: public String getAttributeName(int index) {
117: if (current.attributes == null) {
118: return null;
119: } else {
120: Attribute attribute = (Attribute) current.attributes
121: .get(index);
122: return attribute.name;
123: }
124: }
125:
126: public int getAttributeCount() {
127: return current.attributes == null ? 0 : current.attributes
128: .size();
129: }
130:
131: public Iterator getAttributeNames() {
132: if (current.attributes == null) {
133: return Collections.EMPTY_SET.iterator();
134: } else {
135: final Iterator attributeIterator = current.attributes
136: .iterator();
137: return new Iterator() {
138: public boolean hasNext() {
139: return attributeIterator.hasNext();
140: }
141:
142: public Object next() {
143: Attribute attribute = (Attribute) attributeIterator
144: .next();
145: return attribute.name;
146: }
147:
148: public void remove() {
149: throw new UnsupportedOperationException();
150: }
151: };
152: }
153: }
154:
155: }
|