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.jaxws.support;
019:
020: import java.lang.reflect.ParameterizedType;
021: import java.lang.reflect.Type;
022: import java.util.ArrayList;
023: import java.util.List;
024: import java.util.ResourceBundle;
025: import java.util.logging.Logger;
026:
027: import javax.jws.WebService;
028: import javax.xml.namespace.QName;
029: import javax.xml.ws.BindingType;
030: import javax.xml.ws.Provider;
031: import javax.xml.ws.Service;
032: import javax.xml.ws.ServiceMode;
033: import javax.xml.ws.WebServiceException;
034: import javax.xml.ws.WebServiceProvider;
035: import javax.xml.ws.soap.SOAPBinding;
036:
037: import org.apache.cxf.common.classloader.ClassLoaderUtils;
038: import org.apache.cxf.common.logging.LogUtils;
039: import org.apache.cxf.common.util.PackageUtils;
040: import org.apache.cxf.common.util.StringUtils;
041: import org.apache.cxf.jaxb.JAXBEncoderDecoder;
042:
043: public class JaxWsImplementorInfo {
044:
045: private static final Logger LOG = LogUtils
046: .getL7dLogger(JaxWsImplementorInfo.class);
047: private static final ResourceBundle BUNDLE = LOG
048: .getResourceBundle();
049:
050: private Class<?> implementorClass;
051: private Class<?> seiClass;
052: private List<WebService> wsAnnotations = new ArrayList<WebService>(
053: 2);
054: private WebServiceProvider wsProviderAnnotation;
055:
056: public JaxWsImplementorInfo(Class<?> ic) {
057: implementorClass = ic;
058: initialise();
059: }
060:
061: public Class<?> getSEIClass() {
062: return seiClass;
063: }
064:
065: public Class<?> getImplementorClass() {
066: return implementorClass;
067: }
068:
069: public Class<?> getEndpointClass() {
070: Class endpointInterface = getSEIClass();
071: if (null == endpointInterface) {
072: endpointInterface = getImplementorClass();
073: }
074: return endpointInterface;
075: }
076:
077: public String getWsdlLocation() {
078: for (WebService service : wsAnnotations) {
079: if (!StringUtils.isEmpty(service.wsdlLocation())) {
080: return service.wsdlLocation();
081: }
082: }
083:
084: if (null != wsProviderAnnotation
085: && !StringUtils.isEmpty(wsProviderAnnotation
086: .wsdlLocation())) {
087: return wsProviderAnnotation.wsdlLocation();
088: }
089: return null;
090: }
091:
092: /**
093: * See use of targetNamespace in {@link WebService}.
094: *
095: * @return the qualified name of the service.
096: */
097: public QName getServiceName() {
098: String serviceName = null;
099: String namespace = null;
100:
101: // serviceName cannot be specified on SEI so check impl class only
102: if (wsAnnotations.size() > 0) {
103: int offset = 1;
104: if (seiClass == null) {
105: offset = 0;
106: }
107: //traverse up the parent impl classes for this info as well, but
108: //not the last one which would be the sei annotation
109: for (int x = 0; x < wsAnnotations.size() - offset; x++) {
110: if (StringUtils.isEmpty(serviceName)) {
111: serviceName = wsAnnotations.get(x).serviceName();
112: }
113: if (StringUtils.isEmpty(namespace)) {
114: namespace = wsAnnotations.get(x).targetNamespace();
115: }
116: }
117: }
118:
119: if ((serviceName == null || namespace == null)
120: && wsProviderAnnotation != null) {
121: serviceName = wsProviderAnnotation.serviceName();
122: namespace = wsProviderAnnotation.targetNamespace();
123: }
124:
125: if (StringUtils.isEmpty(serviceName)) {
126: serviceName = implementorClass.getSimpleName() + "Service";
127: }
128:
129: if (StringUtils.isEmpty(namespace)) {
130: namespace = getDefaultNamespace(implementorClass);
131: }
132:
133: return new QName(namespace, serviceName);
134: }
135:
136: /**
137: * See use of targetNamespace in {@link WebService}.
138: *
139: * @return the qualified name of the endpoint.
140: */
141: public QName getEndpointName() {
142: String portName = null;
143: String namespace = null;
144: String name = null;
145:
146: // portName cannot be specified on SEI so check impl class only
147: if (wsAnnotations.size() > 0) {
148: int offset = 1;
149: if (seiClass == null) {
150: offset = 0;
151: }
152: //traverse up the parent impl classes for this info as well, but
153: //not the last one which would be the sei annotation
154: for (int x = 0; x < wsAnnotations.size() - offset; x++) {
155: if (StringUtils.isEmpty(portName)) {
156: portName = wsAnnotations.get(x).portName();
157: }
158: if (StringUtils.isEmpty(namespace)) {
159: namespace = wsAnnotations.get(x).targetNamespace();
160: }
161: if (StringUtils.isEmpty(name)) {
162: name = wsAnnotations.get(x).name();
163: }
164: }
165: }
166:
167: if ((portName == null || namespace == null)
168: && wsProviderAnnotation != null) {
169: portName = wsProviderAnnotation.portName();
170: namespace = wsProviderAnnotation.targetNamespace();
171: }
172: if (StringUtils.isEmpty(portName) && !StringUtils.isEmpty(name)) {
173: portName = name + "Port";
174: }
175: if (StringUtils.isEmpty(portName)) {
176: portName = implementorClass.getSimpleName() + "Port";
177: }
178:
179: if (StringUtils.isEmpty(namespace)) {
180: namespace = getDefaultNamespace(implementorClass);
181: }
182:
183: return new QName(namespace, portName);
184: }
185:
186: public QName getInterfaceName() {
187: String name = null;
188: String namespace = null;
189:
190: if (seiClass != null) {
191: WebService service = seiClass
192: .getAnnotation(WebService.class);
193: if (!StringUtils.isEmpty(service.name())) {
194: name = service.name();
195: }
196: if (!StringUtils.isEmpty(service.targetNamespace())) {
197: namespace = service.targetNamespace();
198: }
199: } else {
200: for (WebService service : wsAnnotations) {
201: if (!StringUtils.isEmpty(service.name())
202: && name == null) {
203: name = service.name();
204: }
205: if (!StringUtils.isEmpty(service.targetNamespace())
206: && namespace == null) {
207: namespace = service.targetNamespace();
208: }
209: }
210: }
211: if (name == null) {
212: if (seiClass != null) {
213: name = seiClass.getSimpleName();
214: } else if (implementorClass != null) {
215: name = implementorClass.getSimpleName();
216: }
217: }
218: if (namespace == null) {
219: if (seiClass != null) {
220: namespace = getDefaultNamespace(seiClass);
221: } else if (implementorClass != null) {
222: namespace = getDefaultNamespace(implementorClass);
223: }
224: }
225:
226: return new QName(namespace, name);
227: }
228:
229: private String getDefaultNamespace(Class clazz) {
230: Package pkg = clazz.getPackage();
231: if (pkg == null) {
232: return null;
233: } else {
234: return PackageUtils.getNamespace(pkg.getName());
235: }
236: }
237:
238: private String getWSInterfaceName(Class implClz) {
239: Class<?>[] clzs = implClz.getInterfaces();
240: for (Class<?> clz : clzs) {
241: if (null != clz.getAnnotation(WebService.class)) {
242: return clz.getName();
243: }
244: }
245: return null;
246: }
247:
248: private String getImplementorClassName() {
249: for (WebService service : wsAnnotations) {
250: if (!StringUtils.isEmpty(service.endpointInterface())) {
251: return service.endpointInterface();
252: }
253: }
254: return null;
255: }
256:
257: private void initialise() {
258: Class<?> cls = implementorClass;
259: while (cls != null) {
260: WebService annotation = cls.getAnnotation(WebService.class);
261: if (annotation != null) {
262: wsAnnotations.add(annotation);
263: }
264: cls = cls.getSuperclass();
265: }
266: String sei = getImplementorClassName();
267: if (StringUtils.isEmpty(sei)) {
268: sei = getWSInterfaceName(implementorClass);
269: }
270: if (!StringUtils.isEmpty(sei)) {
271: try {
272: seiClass = ClassLoaderUtils.loadClass(sei,
273: implementorClass);
274: } catch (ClassNotFoundException ex) {
275: throw new WebServiceException(BUNDLE
276: .getString("SEI_LOAD_FAILURE_MSG"), ex);
277: }
278: WebService seiAnnotation = seiClass
279: .getAnnotation(WebService.class);
280: if (null == seiAnnotation) {
281: throw new WebServiceException(
282: BUNDLE
283: .getString("SEI_WITHOUT_WEBSERVICE_ANNOTATION_EXC"));
284: }
285: if (!StringUtils.isEmpty(seiAnnotation.portName())
286: || !StringUtils
287: .isEmpty(seiAnnotation.serviceName())
288: || !StringUtils.isEmpty(seiAnnotation
289: .endpointInterface())) {
290: String expString = BUNDLE
291: .getString("ILLEGAL_ATTRIBUTE_IN_SEI_ANNOTATION_EXC");
292: throw new WebServiceException(expString);
293: }
294: wsAnnotations.add(seiAnnotation);
295: }
296: wsProviderAnnotation = implementorClass
297: .getAnnotation(WebServiceProvider.class);
298: }
299:
300: public boolean isWebServiceProvider() {
301: return Provider.class.isAssignableFrom(implementorClass);
302: }
303:
304: public WebServiceProvider getWsProvider() {
305: return wsProviderAnnotation;
306: }
307:
308: public Service.Mode getServiceMode() {
309: ServiceMode m = implementorClass
310: .getAnnotation(ServiceMode.class);
311: if (m != null && m.value() != null) {
312: return m.value();
313: }
314: return Service.Mode.PAYLOAD;
315: }
316:
317: public Class<?> getProviderParameterType() {
318: // The Provider Implementor inherits out of Provider<T>
319: Type intfTypes[] = implementorClass.getGenericInterfaces();
320: for (Type t : intfTypes) {
321: Class<?> clazz = JAXBEncoderDecoder.getClassFromType(t);
322: if (Provider.class == clazz) {
323: Type paramTypes[] = ((ParameterizedType) t)
324: .getActualTypeArguments();
325: return JAXBEncoderDecoder
326: .getClassFromType(paramTypes[0]);
327: }
328: }
329: return null;
330: }
331:
332: public String getBindingType() {
333: BindingType bType = implementorClass
334: .getAnnotation(BindingType.class);
335: if (bType != null) {
336: return bType.value();
337: }
338: return SOAPBinding.SOAP11HTTP_BINDING;
339: }
340: }
|