ref #6241 change @date to @since
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / markup / LookAheadEventReader.java
1 /**
2 * Copyright (C) 2009 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9 package eu.etaxonomy.cdm.io.markup;
10
11 import java.util.ArrayList;
12 import java.util.List;
13
14 import javax.xml.stream.XMLEventReader;
15 import javax.xml.stream.XMLStreamException;
16 import javax.xml.stream.events.StartElement;
17 import javax.xml.stream.events.XMLEvent;
18
19 import org.apache.log4j.Logger;
20
21 /**
22 * @author a.mueller
23 \* @since 28.06.2011
24 */
25 public class LookAheadEventReader implements XMLEventReader {
26 private static final Logger logger = Logger.getLogger(LookAheadEventReader.class);
27
28 private XMLEventReader reader;
29
30 private List<XMLEvent> cachedEvents = new ArrayList<>();
31
32 private List<XMLEvent> usedEvents = new ArrayList<>();
33
34 public LookAheadEventReader(StartElement startElement, XMLEventReader parentReader) throws XMLStreamException{
35 int depth = 0;
36 this.reader = parentReader;
37 XMLEvent next = parentReader.nextEvent();
38 while (! next.isEndElement() ||
39 ! next.asEndElement().getName().equals(startElement.getName()) ||
40 depth > 0){
41 cachedEvents.add(next);
42 if (next.isStartElement() && next.asStartElement().getName().equals(startElement.getName())){
43 depth++;
44 }else if (next.isEndElement() && next.asEndElement().getName().equals(startElement.getName())){
45 depth--;
46 }
47 next = reader.nextEvent();
48 }
49 cachedEvents.add(next);
50 }
51
52 @Override
53 public Object next() {
54 throw new RuntimeException("Iterator methods are not supported by this EventReader");
55 }
56
57
58 @Override
59 public void remove() {
60 throw new RuntimeException("Iterator methods are not supported by this EventReader");
61 }
62
63
64 @Override
65 public XMLEvent nextEvent() throws XMLStreamException {
66 if (! cachedEvents.isEmpty()){
67 XMLEvent result = cachedEvents.get(0);
68 XMLEvent removedEvent = cachedEvents.remove(0);
69 usedEvents.add(removedEvent);
70 return result;
71 }else{
72 logger.warn("LookAheadReader reads uncached data. This is not ");
73 throw new IllegalStateException("LookAheadReader reads uncached data. This is not ");
74 // return reader.nextEvent();
75 }
76 }
77
78
79 @Override
80 public boolean hasNext() {
81 return reader.hasNext();
82 }
83
84
85 @Override
86 public XMLEvent peek() throws XMLStreamException {
87 return reader.peek();
88 }
89
90 @Override
91 public String getElementText() throws XMLStreamException {
92 return reader.getElementText();
93 }
94
95 @Override
96 public XMLEvent nextTag() throws XMLStreamException {
97 return reader.nextTag();
98 }
99
100 @Override
101 public Object getProperty(String name) throws IllegalArgumentException {
102 return reader.getProperty(name);
103 }
104
105 @Override
106 public void close() throws XMLStreamException {
107 reader.close();
108 }
109
110 public boolean previousWasEnd(String name){
111 return hasStartElement(name, -1, 0);
112 }
113
114 public boolean nextIsStart(String name){
115 return hasStartElement(name, 0, 1);
116 }
117
118
119 public boolean hasStartElement(String name, int start, int end){
120 if (start < 0 ){
121 start = 0;
122 }
123 if (end > cachedEvents.size()){
124 end = cachedEvents.size();
125 }
126 for (int i = start; i < end; i++){
127
128 XMLEvent ev = cachedEvents.get(i);
129 if (ev.isStartElement() && ev.asStartElement().getName().getLocalPart().equals(name)){
130 return true;
131 }
132 }
133 return false;
134 }
135
136 public boolean hasEndElement(String name, int start, int end){
137 if (end > 0 ){
138 end = 0;
139 }
140 if (-start > usedEvents.size()){
141 start = -cachedEvents.size();
142 }
143 for (int i = start; i < end; i++){
144
145 XMLEvent ev = cachedEvents.get( cachedEvents.size() + i );
146 if (ev.isEndElement() && ev.asEndElement().getName().getLocalPart().equals(name)){
147 return true;
148 }
149 }
150 return false;
151 }
152
153 public List<XMLEvent> getCachedEvents(boolean onlyCharData){
154 List<XMLEvent> result = new ArrayList<>();
155 for (XMLEvent event: cachedEvents){
156 if (!onlyCharData || event.isCharacters()){
157 result.add(event);
158 }
159 }
160 return result;
161 }
162
163 }