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.helpers;
019:
020: import java.lang.reflect.Method;
021: import java.net.MalformedURLException;
022: import java.net.URL;
023: import java.util.StringTokenizer;
024:
025: import javax.xml.namespace.QName;
026:
027: public final class ServiceUtils {
028:
029: private ServiceUtils() {
030: }
031:
032: /**
033: * Generates a suitable service name from a given class. The returned name
034: * is the simple name of the class, i.e. without the package name.
035: *
036: * @param clazz the class.
037: * @return the name.
038: */
039: public static String makeServiceNameFromClassName(Class<?> clazz) {
040: String name = clazz.getName();
041: int last = name.lastIndexOf(".");
042: if (last != -1) {
043: name = name.substring(last + 1);
044: }
045:
046: int inner = name.lastIndexOf("$");
047: if (inner != -1) {
048: name = name.substring(inner + 1);
049: }
050:
051: return name;
052: }
053:
054: public static QName makeQualifiedNameFromClass(Class<?> clazz) {
055: String namespace = makeNamespaceFromClassName(clazz.getName(),
056: "http");
057: String localPart = makeServiceNameFromClassName(clazz);
058: return new QName(namespace, localPart);
059: }
060:
061: public static String getMethodName(Method m) {
062: StringBuffer sb = new StringBuffer();
063: sb.append(m.getDeclaringClass().getName());
064: sb.append('.');
065: sb.append(m.getName());
066: sb.append('(');
067: Class[] params = m.getParameterTypes();
068: for (int i = 0; i < params.length; i++) {
069: Class<?> param = params[i];
070: sb.append(param.getName());
071: if (i < params.length - 1) {
072: sb.append(", ");
073: }
074: }
075: sb.append(')');
076: return sb.toString();
077: }
078:
079: /**
080: * Generates the name of a XML namespace from a given class name and
081: * protocol. The returned namespace will take the form
082: * <code>protocol://domain</code>, where <code>protocol</code> is the
083: * given protocol, and <code>domain</code> the inversed package name of
084: * the given class name. <p/> For instance, if the given class name is
085: * <code>org.codehaus.xfire.services.Echo</code>, and the protocol is
086: * <code>http</code>, the resulting namespace would be
087: * <code>http://services.xfire.codehaus.org</code>.
088: *
089: * @param className the class name
090: * @param protocol the protocol (eg. <code>http</code>)
091: * @return the namespace
092: */
093: public static String makeNamespaceFromClassName(String className,
094: String protocol) {
095: int index = className.lastIndexOf(".");
096:
097: if (index == -1) {
098: return protocol + "://" + "DefaultNamespace";
099: }
100:
101: String packageName = className.substring(0, index);
102:
103: StringTokenizer st = new StringTokenizer(packageName, ".");
104: String[] words = new String[st.countTokens()];
105:
106: for (int i = 0; i < words.length; ++i) {
107: words[i] = st.nextToken();
108: }
109:
110: StringBuffer sb = new StringBuffer(80);
111:
112: for (int i = words.length - 1; i >= 0; --i) {
113: String word = words[i];
114:
115: // seperate with dot
116: if (i != words.length - 1) {
117: sb.append('.');
118: }
119:
120: sb.append(word);
121: }
122:
123: return protocol + "://" + sb.toString() + "/";
124: }
125:
126: /**
127: * Method makePackageName
128: *
129: * @param namespace
130: * @return
131: */
132: public static String makePackageName(String namespace) {
133:
134: String hostname = null;
135: String path = "";
136:
137: // get the target namespace of the document
138: try {
139: URL u = new URL(namespace);
140:
141: hostname = u.getHost();
142: path = u.getPath();
143: } catch (MalformedURLException e) {
144: if (namespace.indexOf(":") > -1) {
145: hostname = namespace
146: .substring(namespace.indexOf(":") + 1);
147:
148: if (hostname.indexOf("/") > -1) {
149: hostname = hostname.substring(0, hostname
150: .indexOf("/"));
151: }
152: } else {
153: hostname = namespace;
154: }
155: }
156:
157: // if we didn't file a hostname, bail
158: if (hostname == null) {
159: return null;
160: }
161:
162: // convert illegal java identifier
163: hostname = hostname.replace('-', '_');
164: path = path.replace('-', '_');
165:
166: // chomp off last forward slash in path, if necessary
167: if ((path.length() > 0)
168: && (path.charAt(path.length() - 1) == '/')) {
169: path = path.substring(0, path.length() - 1);
170: }
171:
172: // tokenize the hostname and reverse it
173: StringTokenizer st = new StringTokenizer(hostname, ".:");
174: String[] words = new String[st.countTokens()];
175:
176: for (int i = 0; i < words.length; ++i) {
177: words[i] = st.nextToken();
178: }
179:
180: StringBuffer sb = new StringBuffer(namespace.length());
181:
182: for (int i = words.length - 1; i >= 0; --i) {
183: addWordToPackageBuffer(sb, words[i], i == words.length - 1);
184: }
185:
186: // tokenize the path
187: StringTokenizer st2 = new StringTokenizer(path, "/");
188:
189: while (st2.hasMoreTokens()) {
190: addWordToPackageBuffer(sb, st2.nextToken(), false);
191: }
192:
193: return sb.toString();
194: }
195:
196: /**
197: * Massage <tt>word</tt> into a form suitable for use in a Java package
198: * name. Append it to the target string buffer with a <tt>.</tt> delimiter
199: * iff <tt>word</tt> is not the first word in the package name.
200: *
201: * @param sb the buffer to append to
202: * @param word the word to append
203: * @param firstWord a flag indicating whether this is the first word
204: */
205: private static void addWordToPackageBuffer(StringBuffer sb,
206: String word, boolean firstWord) {
207:
208: if (JavaUtils.isJavaKeyword(word)) {
209: word = JavaUtils.makeNonJavaKeyword(word);
210: }
211:
212: // separate with dot after the first word
213: if (!firstWord) {
214: sb.append('.');
215: }
216:
217: // prefix digits with underscores
218: if (Character.isDigit(word.charAt(0))) {
219: sb.append('_');
220: }
221:
222: // replace periods with underscores
223: if (word.indexOf('.') != -1) {
224: char[] buf = word.toCharArray();
225:
226: for (int i = 0; i < word.length(); i++) {
227: if (buf[i] == '.') {
228: buf[i] = '_';
229: }
230: }
231:
232: word = new String(buf);
233: }
234:
235: sb.append(word);
236: }
237:
238: }
|