1 package org.objectweb.celtix.bus.jaxws; 2 3 import java.lang.annotation.Annotation ; 4 import java.lang.reflect.InvocationTargetException ; 5 import java.lang.reflect.Method ; 6 import java.util.logging.Level ; 7 import java.util.logging.Logger ; 8 9 import javax.jws.Oneway; 10 import javax.jws.WebMethod; 11 import javax.jws.WebParam; 12 import javax.jws.WebResult; 13 import javax.jws.WebService; 14 import javax.jws.soap.SOAPBinding; 15 import javax.jws.soap.SOAPBinding.Style; 16 import javax.xml.bind.JAXBContext; 17 import javax.xml.namespace.QName ; 18 import javax.xml.soap.Detail ; 19 import javax.xml.soap.SOAPFault ; 20 import javax.xml.validation.Schema ; 21 import javax.xml.ws.AsyncHandler; 22 import javax.xml.ws.Holder; 23 import javax.xml.ws.RequestWrapper; 24 import javax.xml.ws.ResponseWrapper; 25 import javax.xml.ws.WebFault; 26 import javax.xml.ws.WebServiceException; 27 28 import org.w3c.dom.Node ; 29 30 import org.objectweb.celtix.bindings.DataReader; 31 import org.objectweb.celtix.bindings.DataWriter; 32 import org.objectweb.celtix.bindings.ServerDataBindingCallback; 33 import org.objectweb.celtix.bus.bindings.soap.SOAPConstants; 34 import org.objectweb.celtix.bus.bindings.xml.XMLFault; 35 import org.objectweb.celtix.bus.jaxws.io.DetailDataWriter; 36 import org.objectweb.celtix.bus.jaxws.io.NodeDataReader; 37 import org.objectweb.celtix.bus.jaxws.io.NodeDataWriter; 38 import org.objectweb.celtix.bus.jaxws.io.SOAPFaultDataReader; 39 import org.objectweb.celtix.bus.jaxws.io.XMLFaultReader; 40 import org.objectweb.celtix.bus.jaxws.io.XMLFaultWriter; 41 import org.objectweb.celtix.common.logging.LogUtils; 42 import org.objectweb.celtix.context.ObjectMessageContext; 43 import org.objectweb.celtix.jaxb.JAXBUtils; 44 import org.objectweb.celtix.jaxb.WrapperHelper; 45 46 47 public class JAXBDataBindingCallback implements ServerDataBindingCallback { 48 49 private static final Logger LOG = LogUtils.getL7dLogger(JAXBDataBindingCallback.class); 50 51 private SOAPBinding soapBindAnnotation; 52 private WebMethod webMethodAnnotation; 53 private WebResult webResultAnnotation; 54 private Annotation [][] paramAnnotations; 55 private RequestWrapper reqWrapper; 56 private ResponseWrapper respWrapper; 57 private final Method method; 58 private Method syncMethod; 59 private final Mode mode; 60 private WebService webServiceAnnotation; 61 private final JAXBContext context; 62 private final Schema schema; 63 private final EndpointImpl endpoint; 64 private final Object impl; 65 66 public JAXBDataBindingCallback(Method m, Mode md, JAXBContext ctx) { 67 this(m, md, ctx, null); 68 } 69 public JAXBDataBindingCallback(Method m, Mode md, JAXBContext ctx, Schema s) { 70 this(m, md, ctx, s, null); 71 } 72 73 public JAXBDataBindingCallback(Method m, Mode md, JAXBContext ctx, Schema s, EndpointImpl ep) { 74 method = m; 75 mode = md; 76 context = ctx; 77 schema = s; 78 endpoint = ep; 79 impl = null; 80 init(); 81 } 82 public JAXBDataBindingCallback(Method m, Mode md, JAXBContext ctx, Schema s, Object obj) { 83 method = m; 84 mode = md; 85 context = ctx; 86 schema = s; 87 endpoint = null; 88 impl = obj; 89 init(); 90 } 91 92 public JAXBContext getJAXBContext() { 93 return context; 94 } 95 96 public Schema getSchema() { 97 return schema; 98 } 99 100 public Mode getMode() { 101 return mode; 102 } 103 104 105 public Class <?>[] getSupportedFormats() { 106 if (mode == Mode.PARTS) { 107 return new Class <?>[] {Node .class, Detail .class, SOAPFault .class}; 108 } 109 return null; 111 } 112 113 public <T> DataWriter<T> createWriter(Class <T> cls) { 114 if (cls == Node .class) { 115 return new NodeDataWriter<T>(this); 116 } else if (cls == Detail .class) { 117 return new DetailDataWriter<T>(this); 118 } else if (cls == XMLFault.class) { 119 return new XMLFaultWriter<T>(this); 120 } 121 return null; 123 } 124 125 public <T> DataReader<T> createReader(Class <T> cls) { 126 if (cls == Node .class) { 127 return new NodeDataReader<T>(this); 128 } else if (cls == SOAPFault .class) { 129 return new SOAPFaultDataReader<T>(this); 130 } else if (cls == XMLFault.class) { 131 return new XMLFaultReader<T>(this); 132 } 133 return null; 135 } 136 137 private void init() { 138 if (method != null) { 139 webServiceAnnotation = method.getDeclaringClass().getAnnotation(WebService.class); 141 soapBindAnnotation = method.getAnnotation(SOAPBinding.class); 143 if (soapBindAnnotation == null) { 144 soapBindAnnotation = method.getDeclaringClass().getAnnotation(SOAPBinding.class); 145 } 146 webMethodAnnotation = method.getAnnotation(WebMethod.class); 148 paramAnnotations = method.getParameterAnnotations(); 150 webResultAnnotation = method.getAnnotation(WebResult.class); 152 reqWrapper = method.getAnnotation(RequestWrapper.class); 154 respWrapper = method.getAnnotation(ResponseWrapper.class); 156 157 if (JAXBUtils.isAsync(method)) { 158 Class [] paramTypes = method.getParameterTypes(); 159 if (paramTypes != null && paramTypes.length > 0 160 && AsyncHandler.class.isAssignableFrom(paramTypes[paramTypes.length - 1])) { 161 Class [] effectiveParamTypes = new Class [paramTypes.length - 1]; 162 System.arraycopy(paramTypes, 0, effectiveParamTypes, 0, paramTypes.length - 1); 163 paramTypes = effectiveParamTypes; 164 } 165 String syncMethodName = method.getName().substring(0, method.getName().lastIndexOf("Async")); 166 try { 167 syncMethod = method.getDeclaringClass().getMethod(syncMethodName, paramTypes); 168 webResultAnnotation = syncMethod.getAnnotation(WebResult.class); 169 assert null != webResultAnnotation; 170 } catch (NoSuchMethodException ex) { 171 LOG.severe("Could not find method " + syncMethodName 172 + " in class declaring method " + method.getName()); 173 } 174 175 if (null == webResultAnnotation) { 176 webResultAnnotation = syncMethod.getAnnotation(WebResult.class); 177 } 178 } 179 } 180 } 181 182 public boolean isOneWay() { 183 if (method != null) { 184 return method.getAnnotation(Oneway.class) != null; 185 } 186 return false; 187 } 188 189 190 public SOAPBinding.Style getSOAPStyle() { 191 if (null != soapBindAnnotation) { 192 return soapBindAnnotation.style(); 193 } 194 if (endpoint != null) { 195 return endpoint.getStyle(); 196 } 197 return Style.DOCUMENT; 198 } 199 200 public SOAPBinding.Use getSOAPUse() { 201 if (null != soapBindAnnotation) { 202 return soapBindAnnotation.use(); 203 } 204 return SOAPBinding.Use.LITERAL; 205 } 206 207 public SOAPBinding.ParameterStyle getSOAPParameterStyle() { 208 if (null != soapBindAnnotation) { 209 return soapBindAnnotation.parameterStyle(); 210 } 211 return SOAPBinding.ParameterStyle.WRAPPED; 212 } 213 public String getTargetNamespace() { 214 if (webServiceAnnotation == null) { 215 return ""; 216 } 217 return webServiceAnnotation.targetNamespace(); 218 } 219 220 public String getOperationName() { 221 if (null != webMethodAnnotation && !"".equals(webMethodAnnotation.operationName())) { 222 return webMethodAnnotation.operationName(); 223 } 224 if (getMethod() == null) { 225 return ""; 226 } 227 return getMethod().getName(); 228 } 229 230 public String getSOAPAction() { 231 if (null != webMethodAnnotation) { 232 return webMethodAnnotation.action(); 233 } 234 return ""; 235 } 236 237 public WebResult getWebResult() { 238 return webResultAnnotation; 239 } 240 241 public QName getWebResultQName() { 242 if (null != webResultAnnotation) { 243 if (getSOAPStyle() == Style.DOCUMENT) { 244 if ("".equals(webResultAnnotation.name())) { 245 return new QName (webResultAnnotation.targetNamespace(), 246 "return"); 247 } 248 return new QName (webResultAnnotation.targetNamespace(), 249 webResultAnnotation.name()); 250 } else { 251 return new QName ("", webResultAnnotation.partName()); 252 } 253 } 254 return SOAPConstants.EMPTY_QNAME; 255 } 256 257 public WebParam getWebParam(int index) { 258 if (null != paramAnnotations && index < paramAnnotations.length) { 259 for (Annotation annotation : paramAnnotations[index]) { 260 if (WebParam.class.equals(annotation.annotationType())) { 261 return (WebParam)annotation; 262 } 263 } 264 } 265 return null; 266 } 267 268 public QName getRequestWrapperQName() { 269 if (null != reqWrapper) { 270 return new QName (reqWrapper.targetNamespace(), 271 reqWrapper.localName()); 272 } 273 return SOAPConstants.EMPTY_QNAME; 274 } 275 276 public String getRequestWrapperType() { 277 if (null != reqWrapper) { 278 return reqWrapper.className(); 279 } 280 return ""; 281 } 282 283 public QName getResponseWrapperQName() { 284 if (null != respWrapper) { 285 return new QName (respWrapper.targetNamespace(), 286 respWrapper.localName()); 287 } 288 return SOAPConstants.EMPTY_QNAME; 289 } 290 291 public String getResponseWrapperType() { 292 if (null != respWrapper) { 293 return respWrapper.className(); 294 } 295 return ""; 296 } 297 298 public Method getMethod() { 299 return method; 300 } 301 302 public Method getSyncMethod() { 303 return syncMethod; 304 } 305 306 307 public Class <?> getWebFault(QName faultName) { 308 for (Class <?> clazz : getMethod().getExceptionTypes()) { 309 WebFault wfAnnotation = clazz.getAnnotation(WebFault.class); 310 if (wfAnnotation != null 311 && (wfAnnotation.name().equals(faultName.getLocalPart()) 312 && wfAnnotation.targetNamespace().equals(faultName.getNamespaceURI()))) { 313 return clazz; 314 } 315 } 316 return null; 317 } 318 319 public int getParamsLength() { 320 return getMethod() != null 321 ? getMethod().getParameterTypes().length 322 : 0; 323 } 324 325 public Object createWrapperType(ObjectMessageContext objCtx, boolean isOutBound) { 326 String wrapperType = isOutBound ? getResponseWrapperType() 327 : getRequestWrapperType(); 328 329 Object wrapperObj = null; 330 try { 331 332 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 333 if (loader == null) { 334 loader = getClass().getClassLoader(); 335 } 336 337 if (!"".equals(wrapperType)) { 338 wrapperObj = Class.forName(wrapperType, true, loader).newInstance(); 339 } else { 340 return null; 341 } 342 } catch (Exception ex) { 343 throw new WebServiceException("Could not create the wrapper element", ex); 344 } 345 346 if (isOutBound && getWebResult() != null) { 347 setWrappedPart(getWebResultQName().getLocalPart(), wrapperObj, objCtx.getReturn()); 348 } 349 350 WebParam.Mode ignoreParamMode = isOutBound ? WebParam.Mode.IN : WebParam.Mode.OUT; 352 353 int noArgs = getMethod().getParameterTypes().length; 354 355 Object [] args = objCtx.getMessageObjects(); 357 for (int idx = 0; idx < noArgs; idx++) { 358 WebParam param = getWebParam(idx); 359 if ((param.mode() != ignoreParamMode) && !param.header()) { 360 Object wrappedObj = args[idx]; 361 if (param.mode() != WebParam.Mode.IN) { 363 wrappedObj = ((Holder)wrappedObj).value; 364 } 365 if (param.name().equals("asyncHandler") && idx == (noArgs - 1)) { 366 break; 367 } 368 369 setWrappedPart(param.name(), wrapperObj, wrappedObj); 370 } 371 } 372 373 return wrapperObj; 374 } 375 public void setWrappedPart(String name, Object wrapperType, Object part) { 376 try { 377 WrapperHelper.setWrappedPart(name, wrapperType, part); 378 } catch (Exception ex) { 379 throw new WebServiceException("Could not set parts into wrapper element", ex); 380 } 381 } 382 public Object getWrappedPart(String name, Object wrapperType, Class <?> part) { 383 Object obj = null; 384 try { 385 assert wrapperType != null; 386 obj = WrapperHelper.getWrappedPart(name, wrapperType, part); 387 assert obj != null; 388 } catch (Exception ex) { 389 throw new WebServiceException("Could not get part out of wrapper element", ex); 390 } 391 return obj; 392 } 393 394 public void initObjectContext(ObjectMessageContext octx) { 395 if (method != null) { 396 octx.put(ObjectMessageContext.METHOD_OBJ, method); 397 try { 398 int idx = 0; 399 Object [] methodArgs = new Object [method.getParameterTypes().length]; 400 for (Class <?> cls : method.getParameterTypes()) { 401 if (cls.isAssignableFrom(Holder.class)) { 402 methodArgs[idx] = cls.newInstance(); 403 } 404 idx++; 405 } 406 octx.setMessageObjects(methodArgs); 407 } catch (Exception ex) { 408 LOG.log(Level.SEVERE, "INIT_OBJ_CONTEXT_FAILED"); 409 throw new WebServiceException(ex); 410 } 411 } 412 } 413 414 public void invoke(ObjectMessageContext octx) throws InvocationTargetException { 415 Object o = impl; 416 try { 417 if (o == null) { 418 o = endpoint.getImplementor(); 419 } 420 Object ret = method.invoke(o, octx.getMessageObjects()); 421 422 octx.setReturn(ret); 423 } catch (InvocationTargetException e) { 424 throw e; 425 } catch (Exception e) { 426 throw new InvocationTargetException (e); 427 } finally { 428 if (impl == null) { 429 endpoint.releaseImplementor(o); 430 } 431 } 432 } 433 434 435 436 437 } 438 | Popular Tags |