1 package org.textensor.xml;
2
3
4 import java.util.ArrayList;
5 import java.util.StringTokenizer;
6
7 import org.textensor.report.E;
8 import org.textensor.stochdiff.inter.BodyValued;
9
10
11 public class XMLReader {
12
13 ReflectionInstantiator instantiator;
14 int sourceLength;
15 int nerror;
16
17 double progressFraction;
18
19
20 public XMLReader(ReflectionInstantiator insta) {
21 instantiator = insta;
22 }
23
24
25
26
27 public void err(String s) {
28 System.out.println(s);
29 }
30
31
32 public Object readObject(String s) {
33 return readFromString(s);
34 }
35
36
37 public Object read(String s) {
38 return readFromString(s);
39 }
40
41
42
43 public Object readFromString(String s) {
44 s = XMLChecker.deGarbage(s);
45
46 if (s == null) {
47 return null;
48 }
49
50 progressFraction = 0.;
51
52 nerror = 0;
53 sourceLength = (new StringTokenizer(s, "\n")).countTokens();
54
55
56
57 XMLTokenizer tkz = new XMLTokenizer(s);
58
59 XMLToken xmlt = tkz.nextToken();
60 while (xmlt.isIntro() || xmlt.isComment()) {
61
62 if (xmlt.isComment()) {
63 E.info("reading comment " + xmlt);
64 }
65
66
67 xmlt = tkz.nextToken();
68 }
69
70
71
72 XMLHolder xmlHolder = new XMLHolder();
73
74 readFieldIntoParent(tkz, xmlHolder, xmlt);
75
76 return xmlHolder.getContent();
77 }
78
79
80
81 class XMLHolder {
82
83 Object content;
84
85
86 public void setContent(Object obj) {
87 content = obj;
88 }
89
90
91 public Object getContent() {
92 return content;
93 }
94 }
95
96
97
98 public XMLToken readToken(XMLTokenizer tkz) {
99 XMLToken xmlt = tkz.nextToken();
100
101 int lno = tkz.lineno();
102 if (nerror > 4) {
103 err("too many errors - aborting parse at line " + lno);
104
105 }
106
107 return xmlt;
108 }
109
110
111
112 public void readFieldIntoParent(XMLTokenizer tkz, Object parent, XMLToken start) {
113
114
115
116
117
118
119
120
121
122 if (!start.isOpen()) {
123 nerror++;
124 err("ERROR - read object start item was not an open tag " + start);
125 return;
126 }
127
128
129 Object child = null;
130
131 if (parent instanceof String || parent instanceof StringBuffer) {
132 child = new StringBuffer();
133 ((StringBuffer)child).append(start.getOpenTagString());
134
135 } else {
136
137
138
139 Attribute[] atts = start.getAttributes();
140 child = instantiator.getChildObject(parent, start.getName(), atts);
141 if (child != null) {
142 instantiator.applyAttributes(child, atts);
143 }
144
145
146 if (child == null) {
147 child = new ArrayList();
148
149 } else if (child instanceof String) {
150
151
152
153
154 child = new StringBuffer();
155
156
157 } else if (child.getClass().isArray()) {
158
159
160
161 child = new ArrayList();
162 }
163
164
165 if (start.isClose()) {
166
167
168
169
170 } else {
171
172
173
174
175 XMLToken next = readToken(tkz);
176
177 while (true) {
178 if (next.isNone()) {
179
180
181 break;
182
183
184 } else if (next.isOpen()) {
185
186
187 readFieldIntoParent(tkz, child, next);
188
189
190 } else if (next.isClose()) {
191 if (next.closes(start)) {
192
193
194 if (parent instanceof String || parent instanceof StringBuffer) {
195 ((StringBuffer)child).append(next.getCloseTagString());
196 }
197
198
199 } else {
200 nerror++;
201 E.shortError(" non-matching close item \n" + "start Item was: \n"
202 + start.toString() + "\n" + "but close was: \n" + next.toString() + "\n");
203 }
204
205
206
207 break;
208
209
210 } else if (next.isString()) {
211
212
213
214
215
216
217 if (child instanceof ArrayList) {
218 E.error("attempted to read string into array list? - ignored" + next.svalue);
219
220
221
222
223 } else if (child instanceof StringBuffer) {
224
225
226 StringBuffer sbo = (StringBuffer)child;
227 String ssf = sbo.toString();
228 if (ssf.endsWith(">") || next.svalue.startsWith("<") || ssf.length() == 0) {
229 sbo.append(next.svalue);
230
231 } else {
232 sbo.append(" ");
233 sbo.append(next.svalue);
234 }
235
236
237 } else {
238 if (child instanceof String && ((String)child).length() > 0) {
239 child = child + " " + next.svalue;
240
241
242
243 } else if (child == null) {
244 child = next.svalue;
245
246 } else if (child instanceof Double && ((Double)child).doubleValue() == 0.0) {
247 child = new Double(next.svalue);
248
249
250
251 } else if (child instanceof Integer && ((Integer)child).intValue() == 0) {
252 child = new Integer(next.svalue);
253
254 } else if (child instanceof BodyValued) {
255 ((BodyValued)child).setBodyValue(next.svalue);
256
257 } else {
258 instantiator.appendContent(child, next.svalue);
259
260 }
261 }
262
263
264 } else if (next.isNumber()) {
265 E.shortError("XMLReader sjhould never return numbers....!!!! but " + "just got " + next);
266 }
267 next = readToken(tkz);
268 }
269 }
270
271
272
273
274
275
276
277
278 if (child instanceof StringBuffer) {
279 child = ((StringBuffer)child).toString();
280 }
281
282
283
284
285
286
287
288 if (parent instanceof StringBuffer) {
289 StringBuffer psb = (StringBuffer)parent;
290 psb.append(child);
291 psb.append("\n");
292
293
294 } else if (parent instanceof XMLHolder) {
295 ((XMLHolder)parent).setContent(child);
296
297 } else if (parent instanceof ArrayList) {
298 setListChild(parent, child);
299
300 } else {
301 instantiator.setField(parent, start.getName(), child);
302 }
303 }
304 }
305
306
307
308 @SuppressWarnings( {"unchecked"})
309 private void setListChild(Object parent, Object child) {
310 ((ArrayList)parent).add(child);
311 }
312
313 }