001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.servicemix.soap.util.stax;
018
019 import java.util.Collection;
020 import java.util.HashMap;
021 import java.util.HashSet;
022 import java.util.Iterator;
023 import java.util.Map;
024
025 import javax.xml.namespace.NamespaceContext;
026 import javax.xml.stream.XMLStreamConstants;
027 import javax.xml.stream.XMLStreamException;
028 import javax.xml.stream.XMLStreamReader;
029 import javax.xml.stream.util.StreamReaderDelegate;
030
031 public class ExtendedXMLStreamReader extends StreamReaderDelegate {
032
033 private SimpleNamespaceContext context = new SimpleNamespaceContext();
034
035 public ExtendedXMLStreamReader(XMLStreamReader delegate) {
036 super(delegate);
037 }
038
039 public NamespaceContext getNamespaceContext() {
040 return context;
041 }
042
043 public int nextTag() throws XMLStreamException {
044 int eventType = next();
045 while((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace
046 || (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
047 // skip whitespace
048 || eventType == XMLStreamConstants.SPACE
049 || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
050 || eventType == XMLStreamConstants.COMMENT
051 ) {
052 eventType = next();
053 }
054 if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
055 throw new XMLStreamException("expected start or end tag", getLocation());
056 }
057 return eventType;
058 }
059
060 public int next() throws XMLStreamException {
061 int next = super.next();
062 if (next == START_ELEMENT) {
063 context = new SimpleNamespaceContext(context, getNamespaces());
064 } else if (next == END_ELEMENT) {
065 context = context.getParent();
066 }
067 return next;
068 }
069
070 private Map<String, String> getNamespaces() {
071 Map<String,String> ns = new HashMap<String,String>();
072 for (int i = 0; i < getNamespaceCount(); i++) {
073 ns.put(getNamespacePrefix(i), getNamespaceURI(i));
074 }
075 return ns;
076 }
077
078 public static class SimpleNamespaceContext implements ExtendedNamespaceContext {
079
080 private SimpleNamespaceContext parent;
081 private Map<String,String> namespaces;
082
083 public SimpleNamespaceContext() {
084 namespaces = new HashMap<String,String>();
085 }
086
087 public SimpleNamespaceContext(SimpleNamespaceContext parent, Map<String,String> namespaces) {
088 this.parent = parent;
089 this.namespaces = namespaces;
090 }
091
092 public SimpleNamespaceContext getParent() {
093 return parent;
094 }
095
096 public Collection<String> getPrefixes() {
097 HashSet<String> prefixes = new HashSet<String>();
098 for (SimpleNamespaceContext context = this; context != null; context = context.parent) {
099 prefixes.addAll(context.namespaces.keySet());
100 }
101 return prefixes;
102 }
103
104 public String getNamespaceURI(String prefix) {
105 String uri = namespaces.get(prefix);
106 if (uri == null && parent != null) {
107 uri = parent.getNamespaceURI(prefix);
108 }
109 return uri;
110 }
111
112 public String getPrefix(String namespaceURI) {
113 for (SimpleNamespaceContext context = this; context != null; context = context.parent) {
114 for (Map.Entry<String, String> entry : context.namespaces.entrySet()) {
115 if (entry.getValue().equals(namespaceURI)) {
116 return entry.getKey();
117 }
118 }
119 }
120 return null;
121 }
122
123 public Iterator<String> getPrefixes(String namespaceURI) {
124 HashSet<String> prefixes = new HashSet<String>();
125 for (SimpleNamespaceContext context = this; context != null; context = context.parent) {
126 for (Map.Entry<String, String> entry : context.namespaces.entrySet()) {
127 if (entry.getValue().equals(namespaceURI)) {
128 prefixes.add(entry.getKey());
129 }
130 }
131 }
132 return prefixes.iterator();
133 }
134
135 }
136
137
138 }