1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.ws.commons.schema.utils;
21
22 import org.apache.ws.commons.schema.constants.Constants;
23
24 import org.w3c.dom.NamedNodeMap;
25 import org.w3c.dom.Node;
26
27 import javax.xml.namespace.NamespaceContext;
28
29 import java.lang.reflect.Method;
30 import java.util.*;
31
32
33
34
35 public class NodeNamespaceContext implements NamespacePrefixList {
36 private static final String NODE_NAMSPACE_CONTEXT = NamespacePrefixList.class.getName();
37 private static final Collection XML_NS_PREFIX_COLLECTION = Collections.singletonList(Constants.XML_NS_PREFIX);
38 private static final Collection XMLNS_ATTRIBUTE_COLLECTION = Collections.singletonList(Constants.XMLNS_ATTRIBUTE);
39
40 static Method getUserData;
41 static Method setUserData;
42 static {
43 try {
44 Class cls = Class.forName("org.w3c.dom.UserDataHandler", false, Node.class.getClassLoader());
45 getUserData = Node.class.getMethod("getUserData", new Class[]{String.class});
46 setUserData = Node.class.getMethod("setUserData", new Class[]{String.class, Object.class, cls});
47 } catch (Throwable e) {
48 getUserData = null;
49 setUserData = null;
50 }
51 }
52
53
54
55 private final Map declarations;
56 private String[] prefixes;
57
58
59
60
61 private NodeNamespaceContext(Map decls) {
62 declarations = decls;
63 }
64
65 public static NodeNamespaceContext getNamespaceContext(Node pNode) {
66 if (getUserData != null) {
67 try {
68 NodeNamespaceContext ctx = (NodeNamespaceContext)getUserData.invoke(pNode, new Object[] {NODE_NAMSPACE_CONTEXT});
69 if (ctx == null) {
70 Map declarations = new HashMap();
71
72 Node parentNode = pNode.getParentNode();
73 if (parentNode != null) {
74 NodeNamespaceContext parent =
75 (NodeNamespaceContext)getUserData.invoke(parentNode, new Object[] {NODE_NAMSPACE_CONTEXT});
76 if (parent == null) {
77 parent = getNamespaceContext(parentNode);
78 }
79 declarations.putAll(parent.declarations);
80 }
81
82 NamedNodeMap map = pNode.getAttributes();
83 if (map != null) {
84 for (int i = 0; i < map.getLength(); i++) {
85 Node attr = map.item(i);
86 final String uri = attr.getNamespaceURI();
87 if (Constants.XMLNS_ATTRIBUTE_NS_URI.equals(uri)) {
88 String localName = attr.getLocalName();
89 String prefix = Constants.XMLNS_ATTRIBUTE.equals(localName) ? Constants.DEFAULT_NS_PREFIX : localName;
90 declarations.put(prefix, attr.getNodeValue());
91 }
92 }
93 }
94 ctx = new NodeNamespaceContext(declarations);
95 setUserData.invoke(pNode, new Object[] {NODE_NAMSPACE_CONTEXT, ctx, null});
96 }
97 return ctx;
98 } catch (Throwable t) {
99
100
101 }
102 }
103
104 final Map declarations = new HashMap();
105 new PrefixCollector(){
106 protected void declare(String pPrefix, String pNamespaceURI) {
107 declarations.put(pPrefix, pNamespaceURI);
108 }
109 }.searchAllPrefixDeclarations(pNode);
110 return new NodeNamespaceContext(declarations);
111 }
112
113 public String getNamespaceURI(String pPrefix) {
114 if (pPrefix == null) {
115 throw new IllegalArgumentException("The prefix must not be null.");
116 }
117 if (Constants.XML_NS_PREFIX.equals(pPrefix)) {
118 return Constants.XML_NS_URI;
119 }
120 if (Constants.XMLNS_ATTRIBUTE.equals(pPrefix)) {
121 return Constants.XMLNS_ATTRIBUTE_NS_URI;
122 }
123 final String uri = (String) declarations.get(pPrefix);
124 return uri == null ? Constants.NULL_NS_URI : uri;
125 }
126
127 public String getPrefix(String pNamespaceURI) {
128 if (pNamespaceURI == null) {
129 throw new IllegalArgumentException("The namespace URI must not be null.");
130 }
131 if (Constants.XML_NS_URI.equals(pNamespaceURI)) {
132 return Constants.XML_NS_PREFIX;
133 }
134 if (Constants.XMLNS_ATTRIBUTE_NS_URI.equals(pNamespaceURI)) {
135 return Constants.XMLNS_ATTRIBUTE;
136 }
137 for (Iterator iter = declarations.entrySet().iterator(); iter.hasNext(); ) {
138 Map.Entry entry = (Map.Entry) iter.next();
139 if (pNamespaceURI.equals(entry.getValue())) {
140 return (String) entry.getKey();
141 }
142 }
143 return null;
144 }
145
146 public Iterator getPrefixes(String pNamespaceURI) {
147 if (pNamespaceURI == null) {
148 throw new IllegalArgumentException("The namespace URI must not be null.");
149 }
150 if (Constants.XML_NS_URI.equals(pNamespaceURI)) {
151 return XML_NS_PREFIX_COLLECTION.iterator();
152 }
153 if (Constants.XMLNS_ATTRIBUTE_NS_URI.equals(pNamespaceURI)) {
154 return XMLNS_ATTRIBUTE_COLLECTION.iterator();
155 }
156 final List list = new ArrayList();
157 for (Iterator iter = declarations.entrySet().iterator(); iter.hasNext(); ) {
158 Map.Entry entry = (Map.Entry) iter.next();
159 if (pNamespaceURI.equals(entry.getValue())) {
160 list.add(entry.getKey());
161 }
162 }
163 return list.iterator();
164 }
165
166 public String[] getDeclaredPrefixes() {
167 if (prefixes == null) {
168 Collection keys = declarations.keySet();
169 prefixes = (String[]) keys.toArray(new String[keys.size()]);
170 }
171 return prefixes;
172 }
173 }