1 package com.thoughtworks.xstream.io.xml; 2 3 import com.thoughtworks.xstream.core.util.FastStack; 4 import com.thoughtworks.xstream.io.AttributeNameIterator; 5 import com.thoughtworks.xstream.io.HierarchicalStreamReader; 6 7 import java.util.Iterator ; 8 9 16 public abstract class AbstractPullReader implements HierarchicalStreamReader { 17 18 protected static final int START_NODE = 1; 19 protected static final int END_NODE = 2; 20 protected static final int TEXT = 3; 21 protected static final int COMMENT = 4; 22 protected static final int OTHER = 0; 23 24 private final FastStack elementStack = new FastStack(16); 25 26 private final FastStack lookahead = new FastStack(4); 27 private final FastStack lookback = new FastStack(4); 28 private boolean marked; 29 30 private static class Event { 31 int type; 32 String value; 33 } 34 35 44 protected abstract int pullNextEvent(); 45 46 49 protected abstract String pullElementName(); 50 51 54 protected abstract String pullText(); 55 56 public boolean hasMoreChildren() { 57 mark(); 58 while (true) { 59 switch (readEvent().type) { 60 case START_NODE: 61 reset(); 62 return true; 63 case END_NODE: 64 reset(); 65 return false; 66 default: 67 continue; 68 } 69 } 70 } 71 72 public void moveDown() { 73 int currentDepth = elementStack.size(); 74 while (elementStack.size() <= currentDepth) { 75 move(); 76 if (elementStack.size() < currentDepth) { 77 throw new RuntimeException (); } 79 } 80 } 81 82 public void moveUp() { 83 int currentDepth = elementStack.size(); 84 while (elementStack.size() >= currentDepth) { 85 move(); 86 } 87 } 88 89 private void move() { 90 switch (readEvent().type) { 91 case START_NODE: 92 elementStack.push(pullElementName()); 93 break; 94 case END_NODE: 95 elementStack.pop(); 96 break; 97 } 98 } 99 100 private Event readEvent() { 101 if (marked) { 102 if (lookback.hasStuff()) { 103 return (Event) lookahead.push(lookback.pop()); 104 } else { 105 return (Event) lookahead.push(readRealEvent()); 106 } 107 } else { 108 if (lookback.hasStuff()) { 109 return (Event) lookback.pop(); 110 } else { 111 return readRealEvent(); 112 } 113 } 114 } 115 116 private Event readRealEvent() { 117 Event event = new Event(); 118 event.type = pullNextEvent(); 119 if (event.type == TEXT) { 120 event.value = pullText(); 121 } else if (event.type == START_NODE) { 122 event.value = pullElementName(); 123 } 124 return event; 125 } 126 127 public void mark() { 128 marked = true; 129 } 130 131 public void reset() { 132 while(lookahead.hasStuff()) { 133 lookback.push(lookahead.pop()); 134 } 135 marked = false; 136 } 137 138 public String getValue() { 139 142 String last = null; 145 StringBuffer buffer = null; 146 147 mark(); 148 Event event = readEvent(); 149 while (true) { 150 if (event.type == TEXT) { 151 String text = event.value; 152 if (text != null && text.length() > 0) { 153 if (last == null) { 154 last = text; 155 } else { 156 if (buffer == null) { 157 buffer = new StringBuffer (last); 158 } 159 buffer.append(text); 160 } 161 } 162 } else if (event.type != COMMENT) { 163 break; 164 } 165 event = readEvent(); 166 } 167 reset(); 168 if (buffer != null) { 169 return buffer.toString(); 170 } else { 171 return (last == null) ? "" : last; 172 } 173 } 174 175 public Iterator getAttributeNames() { 176 return new AttributeNameIterator(this); 177 } 178 179 public String getNodeName() { 180 return (String ) elementStack.peek(); 181 } 182 183 public Object peekUnderlyingNode() { 184 throw new UnsupportedOperationException (); 185 } 186 187 public HierarchicalStreamReader underlyingReader() { 188 return this; 189 } 190 191 } 192 | Popular Tags |