source: SRUClient/trunk/src/main/java/eu/clarin/sru/client/XmlStreamReaderProxy.java @ 2088

Last change on this file since 2088 was 2088, checked in by oschonef, 12 years ago
  • add JavaDocs? to public API
  • fix wrong constructor visibility with *Request classes
  • do a better job in hiding some non-public API
  • Property svn:eol-style set to native
File size: 16.6 KB
Line 
1/**
2 * This software is copyright (c) 2011 by
3 *  - Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
4 * This is free software. You can redistribute it
5 * and/or modify it under the terms described in
6 * the GNU General Public License v3 of which you
7 * should have received a copy. Otherwise you can download
8 * it from
9 *
10 *   http://www.gnu.org/licenses/gpl-3.0.txt
11 *
12 * @copyright Institut fuer Deutsche Sprache (http://www.ids-mannheim.de)
13 *
14 * @license http://www.gnu.org/licenses/gpl-3.0.txt
15 *  GNU General Public License v3
16 */
17package eu.clarin.sru.client;
18
19import javax.xml.namespace.NamespaceContext;
20import javax.xml.namespace.QName;
21import javax.xml.stream.Location;
22import javax.xml.stream.XMLStreamConstants;
23import javax.xml.stream.XMLStreamException;
24import javax.xml.stream.XMLStreamReader;
25
26class XmlStreamReaderProxy implements XMLStreamReader {
27    private static enum State {
28        START_DOCUMENT, PROCESSING, END_DOCUMENT, PAST_END_DOCUMENT
29    }
30
31    private XMLStreamReader reader;
32    private State state;
33    private int depth;
34
35    XmlStreamReaderProxy() {
36        super();
37    }
38
39    void reset(XMLStreamReader reader) throws XMLStreamException {
40        this.reader = reader;
41        this.state = State.START_DOCUMENT;
42        this.depth = 0;
43    }
44
45    @Override
46    public void close() throws XMLStreamException {
47    }
48
49    @Override
50    public int getAttributeCount() {
51        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
52                XMLStreamConstants.ATTRIBUTE)) {
53            throw new IllegalStateException(
54                    "Current event is not START_ELEMENT or ATTRIBUTE");
55        }
56        return reader.getAttributeCount();
57    }
58
59    @Override
60    public String getAttributeLocalName(int index) {
61        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
62                XMLStreamConstants.ATTRIBUTE)) {
63            throw new IllegalStateException(
64                    "Current event is not START_ELEMENT or ATTRIBUTE");
65        }
66        return reader.getAttributeLocalName(index);
67    }
68
69    @Override
70    public QName getAttributeName(int index) {
71        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
72                XMLStreamConstants.ATTRIBUTE)) {
73            throw new IllegalStateException(
74                    "Current event is not START_ELEMENT or ATTRIBUTE");
75        }
76        return reader.getAttributeName(index);
77    }
78
79    @Override
80    public String getAttributeNamespace(int index) {
81        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
82                XMLStreamConstants.ATTRIBUTE)) {
83            throw new IllegalStateException(
84                    "Current event is not START_ELEMENT or ATTRIBUTE");
85        }
86        return reader.getAttributeNamespace(index);
87    }
88
89    @Override
90    public String getAttributePrefix(int index) {
91        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
92                XMLStreamConstants.ATTRIBUTE)) {
93            throw new IllegalStateException(
94                    "Current event is not START_ELEMENT or ATTRIBUTE");
95        }
96        return reader.getAttributePrefix(index);
97    }
98
99    @Override
100    public String getAttributeType(int index) {
101        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
102                XMLStreamConstants.ATTRIBUTE)) {
103            throw new IllegalStateException(
104                    "Current event is not START_ELEMENT or ATTRIBUTE");
105        }
106        return reader.getAttributeType(index);
107    }
108
109    @Override
110    public String getAttributeValue(int index) {
111        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
112                XMLStreamConstants.ATTRIBUTE)) {
113            throw new IllegalStateException(
114                    "Current event is not START_ELEMENT or ATTRIBUTE");
115        }
116        return reader.getAttributeValue(index);
117    }
118
119    @Override
120    public String getAttributeValue(String namespaceURI, String localName) {
121        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
122                XMLStreamConstants.ATTRIBUTE)) {
123            throw new IllegalStateException(
124                    "Current event is not START_ELEMENT or ATTRIBUTE");
125        }
126        return reader.getAttributeValue(namespaceURI, localName);
127    }
128
129    @Override
130    public String getCharacterEncodingScheme() {
131        return reader.getCharacterEncodingScheme();
132    }
133
134    @Override
135    public String getElementText() throws XMLStreamException {
136        if (!checkEventType(XMLStreamConstants.START_ELEMENT)) {
137            throw new IllegalStateException(
138                    "Current event is not START_ELEMENT");
139        }
140        return reader.getElementText();
141    }
142
143    @Override
144    public String getEncoding() {
145        return reader.getEncoding();
146    }
147
148    @Override
149    public int getEventType() {
150        switch (state) {
151        case START_DOCUMENT:
152            return XMLStreamConstants.START_DOCUMENT;
153        case PROCESSING:
154            return reader.getEventType();
155        case END_DOCUMENT:
156            return XMLStreamConstants.END_DOCUMENT;
157        case PAST_END_DOCUMENT:
158            throw new IllegalStateException("past end of document");
159        default:
160            throw new RuntimeException("invalid internel state: " + state);
161        }
162    }
163
164    @Override
165    public String getLocalName() {
166        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
167                XMLStreamConstants.END_ELEMENT,
168                XMLStreamConstants.ENTITY_REFERENCE)) {
169            throw new IllegalStateException("Current event is not "
170                    + "START_ELEMENT, END_ELEMENT or ENTITY_REFERENCE");
171        }
172        return reader.getLocalName();
173    }
174
175    @Override
176    public Location getLocation() {
177        return reader.getLocation();
178    }
179
180    @Override
181    public QName getName() {
182        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
183                XMLStreamConstants.END_ELEMENT)) {
184            throw new IllegalStateException("Current event is not "
185                    + "START_ELEMENT or END_ELEMENT");
186        }
187        return reader.getName();
188    }
189
190    @Override
191    public NamespaceContext getNamespaceContext() {
192        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
193                XMLStreamConstants.END_ELEMENT, XMLStreamConstants.NAMESPACE)) {
194            throw new IllegalStateException("Current event is not "
195                    + "START_ELEMENT, END_ELEMENT or NAMESPACE");
196        }
197        return reader.getNamespaceContext();
198    }
199
200    @Override
201    public int getNamespaceCount() {
202        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
203                XMLStreamConstants.END_ELEMENT, XMLStreamConstants.NAMESPACE)) {
204            throw new IllegalStateException("Current event is not "
205                    + "START_ELEMENT, END_ELEMENT or NAMESPACE");
206        }
207        return reader.getNamespaceCount();
208    }
209
210    @Override
211    public String getNamespacePrefix(int index) {
212        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
213                XMLStreamConstants.END_ELEMENT, XMLStreamConstants.NAMESPACE)) {
214            throw new IllegalStateException("Current event is not "
215                    + "START_ELEMENT, END_ELEMENT or NAMESPACE");
216        }
217        return reader.getNamespacePrefix(index);
218    }
219
220    @Override
221    public String getNamespaceURI() {
222        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
223                XMLStreamConstants.END_ELEMENT, XMLStreamConstants.NAMESPACE)) {
224            throw new IllegalStateException("Current event is not "
225                    + "START_ELEMENT, END_ELEMENT or NAMESPACE");
226        }
227        return reader.getNamespaceURI();
228    }
229
230    @Override
231    public String getNamespaceURI(String prefix) {
232        return reader.getNamespaceURI(prefix);
233    }
234
235    @Override
236    public String getNamespaceURI(int index) {
237        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
238                XMLStreamConstants.END_ELEMENT, XMLStreamConstants.NAMESPACE)) {
239            throw new IllegalStateException("Current event is not "
240                    + "START_ELEMENT, END_ELEMENT or NAMESPACE");
241        }
242        return reader.getNamespaceURI(index);
243    }
244
245    @Override
246    public String getPIData() {
247        if (!checkEventType(XMLStreamConstants.PROCESSING_INSTRUCTION)) {
248            throw new IllegalStateException(
249                    "Current event is not PROCESSING_INSTRUCTION");
250        }
251        return reader.getPIData();
252    }
253
254    @Override
255    public String getPITarget() {
256        if (!checkEventType(XMLStreamConstants.PROCESSING_INSTRUCTION)) {
257            throw new IllegalStateException(
258                    "Current event is not PROCESSING_INSTRUCTION");
259        }
260        return reader.getPITarget();
261    }
262
263    @Override
264    public String getPrefix() {
265        return reader.getPrefix();
266    }
267
268    @Override
269    public Object getProperty(String name) throws IllegalArgumentException {
270        return reader.getProperty(name);
271    }
272
273    @Override
274    public String getText() {
275        if (!checkEventTypes(XMLStreamConstants.CHARACTERS,
276                XMLStreamConstants.CDATA, XMLStreamConstants.COMMENT,
277                XMLStreamConstants.SPACE, XMLStreamConstants.ENTITY_REFERENCE)) {
278            throw new IllegalStateException("Current event is a text event");
279        }
280        return reader.getText();
281    }
282
283    @Override
284    public char[] getTextCharacters() {
285        if (!checkEventTypes(XMLStreamConstants.CHARACTERS,
286                XMLStreamConstants.CDATA, XMLStreamConstants.COMMENT,
287                XMLStreamConstants.SPACE)) {
288            throw new IllegalStateException("Current event is a text event");
289        }
290        return reader.getTextCharacters();
291    }
292
293    @Override
294    public int getTextCharacters(int sourceStart, char[] target,
295            int targetStart, int length) throws XMLStreamException {
296        if (!checkEventTypes(XMLStreamConstants.CHARACTERS,
297                XMLStreamConstants.CDATA, XMLStreamConstants.COMMENT,
298                XMLStreamConstants.SPACE)) {
299            throw new UnsupportedOperationException(
300                    "Current event is a text event");
301        }
302        return reader.getTextCharacters(sourceStart, target, targetStart,
303                length);
304    }
305
306    @Override
307    public int getTextLength() {
308        if (!checkEventTypes(XMLStreamConstants.CHARACTERS,
309                XMLStreamConstants.CDATA, XMLStreamConstants.COMMENT,
310                XMLStreamConstants.SPACE)) {
311            throw new IllegalStateException("invalid state");
312        }
313        return reader.getTextLength();
314    }
315
316    @Override
317    public int getTextStart() {
318        if (!checkEventTypes(XMLStreamConstants.CHARACTERS,
319                XMLStreamConstants.CDATA, XMLStreamConstants.COMMENT,
320                XMLStreamConstants.SPACE)) {
321            throw new IllegalStateException("invalid state");
322        }
323        return reader.getTextStart();
324    }
325
326    @Override
327    public String getVersion() {
328        return reader.getVersion();
329    }
330
331    @Override
332    public boolean hasName() {
333        switch (state) {
334        case START_DOCUMENT:
335            /* FALL-THOUGH */
336        case END_DOCUMENT:
337            /* FALL-THOUGH */
338        case PAST_END_DOCUMENT:
339            return false;
340        default:
341            return reader.hasName();
342        }
343    }
344
345    @Override
346    public boolean hasNext() throws XMLStreamException {
347        if (state == State.END_DOCUMENT) {
348            return false;
349        }
350        return true;
351    }
352
353    @Override
354    public boolean hasText() {
355        switch (state) {
356        case START_DOCUMENT:
357            /* FALL-THOUGH */
358        case END_DOCUMENT:
359            /* FALL-THOUGH */
360        case PAST_END_DOCUMENT:
361            return false;
362        default:
363            return reader.hasText();
364        } // switch
365    }
366
367    @Override
368    public boolean isAttributeSpecified(int index) {
369        if (!checkEventTypes(XMLStreamConstants.START_ELEMENT,
370                XMLStreamConstants.ATTRIBUTE)) {
371            throw new IllegalStateException(
372                    "Current event is not START_ELEMENT or ATTRIBUTE");
373        }
374        return reader.isAttributeSpecified(index);
375    }
376
377    @Override
378    public boolean isCharacters() {
379        switch (state) {
380        case START_DOCUMENT:
381            /* FALL-THOUGH */
382        case END_DOCUMENT:
383            /* FALL-THOUGH */
384        case PAST_END_DOCUMENT:
385            return false;
386        default:
387            return reader.isCharacters();
388        }
389    }
390
391    @Override
392    public boolean isEndElement() {
393        switch (state) {
394        case START_DOCUMENT:
395            /* FALL-THOUGH */
396        case END_DOCUMENT:
397            /* FALL-THOUGH */
398        case PAST_END_DOCUMENT:
399            return false;
400        default:
401            return reader.isEndElement();
402        }
403    }
404
405    @Override
406    public boolean isStandalone() {
407        return reader.isStandalone();
408    }
409
410    @Override
411    public boolean isStartElement() {
412        switch (state) {
413        case START_DOCUMENT:
414            /* FALL-THOUGH */
415        case END_DOCUMENT:
416            /* FALL-THOUGH */
417        case PAST_END_DOCUMENT:
418            return false;
419        default:
420            return reader.isStartElement();
421        }
422    }
423
424    @Override
425    public boolean isWhiteSpace() {
426        switch (state) {
427        case START_DOCUMENT:
428            /* FALL-THOUGH */
429        case END_DOCUMENT:
430            return true;
431        case PAST_END_DOCUMENT:
432            return false;
433        default:
434            return reader.isWhiteSpace();
435        }
436    }
437
438    @Override
439    public int next() throws XMLStreamException {
440        int type = -1;
441        switch (state) {
442        case START_DOCUMENT:
443            state = State.PROCESSING;
444            type = reader.getEventType();
445            if (type == XMLStreamConstants.START_ELEMENT) {
446                depth++;
447            }
448            break;
449        case PROCESSING:
450            type = reader.next();
451            switch (type) {
452            case XMLStreamConstants.START_ELEMENT:
453                depth++;
454                break;
455            case XMLStreamConstants.END_ELEMENT:
456                depth--;
457                break;
458            default:
459                ;
460            } // switch (t)
461            if (depth < 0) {
462                state = State.END_DOCUMENT;
463                type = XMLStreamConstants.END_DOCUMENT;
464            }
465            break;
466        case END_DOCUMENT:
467            state = State.PAST_END_DOCUMENT;
468            type = XMLStreamConstants.END_DOCUMENT;
469            break;
470        default:
471            throw new IllegalStateException("past end of input");
472        } // switch (state)
473        return type;
474    }
475
476    @Override
477    public int nextTag() throws XMLStreamException {
478        boolean skip = true;
479        int type = getEventType();
480        do {
481            switch (type) {
482            case XMLStreamConstants.CHARACTERS:
483                /* FALL_TROUGH */
484            case XMLStreamConstants.CDATA:
485                if (!isWhiteSpace()) {
486                    skip = false;
487                    break;
488                }
489            case XMLStreamConstants.START_DOCUMENT:
490                /* FALL_TROUGH */
491            case XMLStreamConstants.SPACE:
492                /* FALL_TROUGH */
493            case XMLStreamConstants.PROCESSING_INSTRUCTION:
494                /* FALL_TROUGH */
495            case XMLStreamConstants.COMMENT:
496                type = next();
497                break;
498            default:
499                skip = false;
500            } // switch
501        } while (skip);
502        if ((type != XMLStreamConstants.START_ELEMENT) &&
503                (type != XMLStreamConstants.END_ELEMENT)) {
504            throw new XMLStreamException("expected start or end tag",
505                    getLocation());
506        }
507        return type;
508    }
509
510    @Override
511    public void require(int type, String namespaceURI, String localName)
512            throws XMLStreamException {
513        reader.require(type, namespaceURI, localName);
514    }
515
516    @Override
517    public boolean standaloneSet() {
518        return reader.standaloneSet();
519    }
520
521    private boolean checkEventType(int type) {
522        switch (state) {
523        case START_DOCUMENT:
524            return XMLStreamConstants.START_DOCUMENT == type;
525        case END_DOCUMENT:
526            return XMLStreamConstants.END_DOCUMENT == type;
527        case PAST_END_DOCUMENT:
528            return false;
529        default:
530            return reader.getEventType() == type;
531        } // switch
532    }
533
534    private boolean checkEventTypes(int... types) {
535        if (state == State.PROCESSING) {
536            for (int type : types) {
537                if (type == reader.getEventType()) {
538                    return true;
539                }
540            }
541        }
542        return false;
543    }
544
545} // class XmlStreamReaderWrapper
Note: See TracBrowser for help on using the repository browser.