1 package org.codehaus.xfire.util;
2
3 import java.util.StringTokenizer;
4
5 import javax.xml.stream.XMLStreamException;
6 import javax.xml.stream.XMLStreamWriter;
7
8 import org.codehaus.yom.Element;
9
10 /***
11 * Namespace utilities.
12 *
13 * @author <a href="mailto:dan@envoisolutions.com">Dan Diephouse</a>
14 * @author <a href="mailto:poutsma@mac.com">Arjen Poutsma</a>
15 */
16 public class NamespaceHelper
17 {
18 /***
19 * Create a unique namespace uri/prefix combination.
20 *
21 * @param nsUri
22 * @return The namespace with the specified URI. If one doesn't exist, one is created.
23 */
24 public static String getUniquePrefix(Element element, String namespaceURI)
25 {
26 String prefix = element.getNamespacePrefix(namespaceURI);
27 if (prefix == null)
28 {
29 prefix = getUniquePrefix(element);
30 element.addNamespaceDeclaration(prefix, namespaceURI);
31 }
32 return prefix;
33 }
34
35 private static String getUniquePrefix(Element el)
36 {
37 int n = 1;
38
39 while (true)
40 {
41 String nsPrefix = "ns" + n;
42
43 if (el.getNamespaceURI(nsPrefix) == null)
44 return nsPrefix;
45
46 n++;
47 }
48 }
49
50 /***
51 * Create a unique namespace uri/prefix combination.
52 *
53 * @param nsUri
54 * @return The namespace with the specified URI. If one doesn't exist, one is created.
55 * @throws XMLStreamException
56 */
57 public static String getUniquePrefix(XMLStreamWriter writer, String namespaceURI, boolean declare)
58 throws XMLStreamException
59 {
60 String prefix = writer.getPrefix(namespaceURI);
61 if (prefix == null)
62 {
63 prefix = getUniquePrefix(writer);
64
65 if (declare)
66 writer.writeNamespace(prefix, namespaceURI);
67 }
68 return prefix;
69 }
70
71 public static String getUniquePrefix(XMLStreamWriter writer)
72 {
73 int n = 1;
74
75 while (true)
76 {
77 String nsPrefix = "ns" + n;
78
79 if (writer.getNamespaceContext().getNamespaceURI(nsPrefix) == null)
80 {
81 return nsPrefix;
82 }
83
84 n++;
85 }
86 }
87
88 /***
89 * Generates the name of a XML namespace from a given class name and protocol. The returned namespace will take the
90 * form <code>protocol://domain</code>, where <code>protocol</code> is the given protocol, and <code>domain</code>
91 * the inversed package name of the given class name.
92 * <p/>
93 * For instance, if the given class name is <code>org.codehaus.xfire.services.Echo</code>, and the protocol is
94 * <code>http</code>, the resulting namespace would be <code>http://services.xfire.codehaus.org</code>.
95 *
96 * @param className the class name
97 * @param protocol the protocol (eg. <code>http</code>)
98 * @return the namespace
99 */
100 public static String makeNamespaceFromClassName(String className, String protocol)
101 {
102 int index = className.lastIndexOf(".");
103
104 if (index == -1)
105 {
106 return protocol + "://" + "DefaultNamespace";
107 }
108
109 String packageName = className.substring(0, index);
110
111 StringTokenizer st = new StringTokenizer(packageName, ".");
112 String[] words = new String[st.countTokens()];
113
114 for (int i = 0; i < words.length; ++i)
115 {
116 words[i] = st.nextToken();
117 }
118
119 StringBuffer sb = new StringBuffer(80);
120
121 for (int i = words.length - 1; i >= 0; --i)
122 {
123 String word = words[i];
124
125
126 if (i != words.length - 1)
127 {
128 sb.append('.');
129 }
130
131 sb.append(word);
132 }
133
134 return protocol + "://" + sb.toString();
135 }
136 }