001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */package org.apache.cxf.aegis.util.stax;
019:
020: import java.util.ArrayList;
021: import java.util.HashMap;
022: import java.util.Iterator;
023: import java.util.List;
024: import java.util.Map;
025:
026: import javax.xml.namespace.NamespaceContext;
027: import javax.xml.namespace.QName;
028: import javax.xml.stream.XMLStreamException;
029:
030: import org.apache.cxf.staxutils.AbstractDOMStreamReader;
031: import org.apache.cxf.staxutils.FastStack;
032: import org.jdom.Attribute;
033: import org.jdom.CDATA;
034: import org.jdom.Comment;
035: import org.jdom.Content;
036: import org.jdom.Document;
037: import org.jdom.Element;
038: import org.jdom.EntityRef;
039: import org.jdom.Namespace;
040: import org.jdom.Text;
041:
042: /**
043: * Facade for DOMStreamReader using JDOM implmentation.
044: *
045: * @author <a href="mailto:tsztelak@gmail.com">Tomasz Sztelak</a>
046: */
047: public class JDOMStreamReader extends AbstractDOMStreamReader {
048:
049: private Content content;
050:
051: private FastStack<Map<String, Namespace>> namespaceStack = new FastStack<Map<String, Namespace>>();
052:
053: private List<Namespace> namespaces = new ArrayList<Namespace>();
054:
055: private Map<String, Namespace> prefix2decNs;
056:
057: private JDOMNamespaceContext namespaceContext;
058:
059: /**
060: * @param element
061: */
062: public JDOMStreamReader(Element element) {
063: super (new ElementFrame(element, null));
064:
065: namespaceContext = new JDOMNamespaceContext();
066: setupNamespaces(element);
067: }
068:
069: /**
070: * @param document
071: */
072: public JDOMStreamReader(Document document) {
073: this (document.getRootElement());
074: }
075:
076: public static String toStaxType(int jdom) {
077: String val;
078: switch (jdom) {
079: case Attribute.CDATA_TYPE:
080: val = "CDATA";
081: break;
082: case Attribute.ID_TYPE:
083: val = "ID";
084: break;
085: case Attribute.IDREF_TYPE:
086: val = "IDREF";
087: break;
088: case Attribute.IDREFS_TYPE:
089: val = "IDREFS";
090: break;
091: case Attribute.ENTITY_TYPE:
092: val = "ENTITY";
093: break;
094: case Attribute.ENTITIES_TYPE:
095: val = "ENTITIES";
096: break;
097: case Attribute.ENUMERATED_TYPE:
098: val = "ENUMERATED";
099: break;
100: case Attribute.NMTOKEN_TYPE:
101: val = "NMTOKEN";
102: break;
103: case Attribute.NMTOKENS_TYPE:
104: val = "NMTOKENS";
105: break;
106: case Attribute.NOTATION_TYPE:
107: val = "NOTATION";
108: break;
109: default:
110: val = null;
111: }
112: return val;
113: }
114:
115: private void setupNamespaces(Element element) {
116: namespaceContext.setElement(element);
117:
118: if (prefix2decNs != null) {
119: namespaceStack.push(prefix2decNs);
120: }
121:
122: prefix2decNs = new HashMap<String, Namespace>();
123: namespaces.clear();
124:
125: for (Iterator itr = element.getAdditionalNamespaces()
126: .iterator(); itr.hasNext();) {
127: declare((Namespace) itr.next());
128: }
129:
130: Namespace ns = element.getNamespace();
131:
132: if (shouldDeclare(ns)) {
133: declare(ns);
134: }
135:
136: for (Iterator itr = element.getAttributes().iterator(); itr
137: .hasNext();) {
138: ns = ((Attribute) itr.next()).getNamespace();
139: if (shouldDeclare(ns)) {
140: declare(ns);
141: }
142: }
143: }
144:
145: private void declare(Namespace ns) {
146: prefix2decNs.put(ns.getPrefix(), ns);
147: namespaces.add(ns);
148: }
149:
150: private boolean shouldDeclare(Namespace ns) {
151: if (ns == Namespace.XML_NAMESPACE) {
152: return false;
153: }
154:
155: if (ns == Namespace.NO_NAMESPACE && getDeclaredURI("") == null) {
156: return false;
157: }
158:
159: String decUri = getDeclaredURI(ns.getPrefix());
160:
161: return !(decUri != null && decUri.equals(ns.getURI()));
162: }
163:
164: private String getDeclaredURI(String string) {
165: for (int i = namespaceStack.size() - 1; i == 0; i--) {
166: Map<String, Namespace> nmspaces = namespaceStack.get(i);
167:
168: Namespace dec = nmspaces.get(string);
169:
170: if (dec != null) {
171: return dec.getURI();
172: }
173: }
174: return null;
175: }
176:
177: @Override
178: @SuppressWarnings("unchecked")
179: protected void endElement() {
180: if (namespaceStack.size() > 0) {
181: prefix2decNs = (Map<String, Namespace>) namespaceStack
182: .pop();
183: }
184: }
185:
186: public Element getCurrentElement() {
187: return (Element) getCurrentFrame().getElement();
188: }
189:
190: @Override
191: protected ElementFrame getChildFrame(int currentChild) {
192: return new ElementFrame(getCurrentElement().getContent(
193: currentChild), getCurrentFrame());
194: }
195:
196: @Override
197: protected int getChildCount() {
198: return getCurrentElement().getContentSize();
199: }
200:
201: @Override
202: protected int moveToChild(int currentChild) {
203: this .content = getCurrentElement().getContent(currentChild);
204:
205: if (content instanceof Text) {
206: return CHARACTERS;
207: } else if (content instanceof Element) {
208: setupNamespaces((Element) content);
209: return START_ELEMENT;
210: } else if (content instanceof CDATA) {
211: return CHARACTERS;
212: } else if (content instanceof Comment) {
213: return CHARACTERS;
214: } else if (content instanceof EntityRef) {
215: return ENTITY_REFERENCE;
216: }
217:
218: throw new IllegalStateException();
219: }
220:
221: @Override
222: public String getElementText() throws XMLStreamException {
223: return ((Text) content).getText();
224: }
225:
226: @Override
227: public String getNamespaceURI(String prefix) {
228: return getCurrentElement().getNamespace(prefix).getURI();
229: }
230:
231: public String getAttributeValue(String ns, String local) {
232: return getCurrentElement().getAttributeValue(local,
233: Namespace.getNamespace(ns));
234: }
235:
236: public int getAttributeCount() {
237: return getCurrentElement().getAttributes().size();
238: }
239:
240: Attribute getAttribute(int i) {
241: return (Attribute) getCurrentElement().getAttributes().get(i);
242: }
243:
244: public QName getAttributeName(int i) {
245: Attribute at = getAttribute(i);
246:
247: return new QName(at.getNamespaceURI(), at.getName(), at
248: .getNamespacePrefix());
249: }
250:
251: public String getAttributeNamespace(int i) {
252: return getAttribute(i).getNamespaceURI();
253: }
254:
255: public String getAttributeLocalName(int i) {
256: return getAttribute(i).getName();
257: }
258:
259: public String getAttributePrefix(int i) {
260: return getAttribute(i).getNamespacePrefix();
261: }
262:
263: public String getAttributeType(int i) {
264: return toStaxType(getAttribute(i).getAttributeType());
265: }
266:
267: public String getAttributeValue(int i) {
268: return getAttribute(i).getValue();
269: }
270:
271: public boolean isAttributeSpecified(int i) {
272: return getAttribute(i).getValue() != null;
273: }
274:
275: public int getNamespaceCount() {
276: return namespaces.size();
277: }
278:
279: Namespace getNamespace(int i) {
280: return namespaces.get(i);
281: }
282:
283: public String getNamespacePrefix(int i) {
284: return getNamespace(i).getPrefix();
285: }
286:
287: public String getNamespaceURI(int i) {
288: return getNamespace(i).getURI();
289: }
290:
291: public NamespaceContext getNamespaceContext() {
292: return namespaceContext;
293: }
294:
295: public String getText() {
296: return content.getValue();
297: }
298:
299: public char[] getTextCharacters() {
300: return getText().toCharArray();
301: }
302:
303: public int getTextStart() {
304: return 0;
305: }
306:
307: public int getTextLength() {
308: return getText().length();
309: }
310:
311: public String getEncoding() {
312: return null;
313: }
314:
315: public QName getName() {
316: Element el = getCurrentElement();
317:
318: return new QName(el.getNamespaceURI(), el.getName(), el
319: .getNamespacePrefix());
320: }
321:
322: public String getLocalName() {
323: return getCurrentElement().getName();
324: }
325:
326: public String getNamespaceURI() {
327: return getCurrentElement().getNamespaceURI();
328: }
329:
330: public String getPrefix() {
331: return getCurrentElement().getNamespacePrefix();
332: }
333:
334: public String getPITarget() {
335: throw new UnsupportedOperationException();
336: }
337:
338: public String getPIData() {
339: throw new UnsupportedOperationException();
340: }
341: }
|