1 16 package org.apache.beehive.wsm.axis; 17 18 import org.apache.axis.constants.Style; 19 import org.apache.axis.constants.Use; 20 import org.apache.axis.description.*; 21 import org.apache.axis.encoding.*; 22 import org.apache.axis.encoding.ser.ArrayDeserializerFactory; 23 import org.apache.axis.encoding.ser.ArraySerializerFactory; 24 import org.apache.axis.encoding.ser.BeanDeserializerFactory; 25 import org.apache.axis.encoding.ser.BeanSerializerFactory; 26 import org.apache.axis.utils.BeanPropertyDescriptor; 27 import org.apache.axis.utils.BeanUtils; 28 import org.apache.axis.utils.JavaUtils; 29 import org.apache.axis.wsdl.fromJava.Namespaces; 30 import org.apache.axis.wsdl.fromJava.Types; 31 import org.apache.beehive.wsm.axis.databinding.SystemTypeLookupService; 32 import org.apache.beehive.wsm.axis.registration.AxisTypeMappingMetaData; 33 import org.apache.beehive.wsm.axis.util.encoding.XmlBeanDeserializerFactory; 34 import org.apache.beehive.wsm.axis.util.encoding.XmlBeanSerializerFactory; 35 import org.apache.beehive.wsm.databinding.BindingLookupService; 36 import org.apache.beehive.wsm.model.BeehiveWsMethodMetadata; 37 import org.apache.beehive.wsm.model.BeehiveWsParameterMetadata; 38 import org.apache.beehive.wsm.model.BeehiveWsSOAPBindingInfo; 39 import org.apache.beehive.wsm.model.BeehiveWsTypeMetadata; 40 import org.apache.beehive.wsm.util.InvalidTypeMappingException; 41 import org.apache.beehive.wsm.registration.TypeRegistrar; 42 import org.apache.log4j.Logger; 43 import org.apache.xmlbeans.XmlBeans; 44 import org.apache.xmlbeans.XmlObject; 45 46 import javax.jws.WebParam; 47 import javax.jws.soap.SOAPBinding; 48 import javax.wsdl.OperationType; 49 import javax.xml.namespace.QName ; 50 import javax.xml.rpc.holders.Holder ; 51 52 import java.io.File ; 53 import java.lang.reflect.Constructor ; 54 import java.lang.reflect.Method ; 55 import java.rmi.Remote ; 56 import java.util.ArrayList ; 57 import java.util.Collection ; 58 import java.util.List ; 59 import java.util.Map ; 60 61 66 public class AxisHook { 67 static Logger logger = Logger.getLogger(AxisHook.class); 68 69 public static ServiceDesc createServiceDesc(BeehiveWsTypeMetadata wsm, 70 ClassLoader cl) throws ClassNotFoundException , 71 NoSuchMethodException , InvalidTypeMappingException { 72 JavaServiceDesc sd = new JavaServiceDesc(); 73 if (null == cl) { 74 78 cl = AxisHook.class.getClassLoader(); 79 } 80 final Class serviceClass = cl.loadClass(wsm.getClassName()); 81 82 List <String > allowedMethods = new ArrayList <String >(); 84 for (BeehiveWsMethodMetadata meth : wsm.getMethods()) { 85 String method = meth.getJavaMethodName(); 86 allowedMethods.add(method); 87 } 88 89 sd.setName(wsm.getWsName()); 91 sd.setImplClass(serviceClass); 92 String targetNamespace = wsm.getWsTargetNamespace(); 93 sd.setDefaultNamespace(targetNamespace); 94 sd.setAllowedMethods(allowedMethods); 95 configureSoapBinding(sd, wsm.getSoapBinding()); 96 97 TypeMappingRegistry tmr = new TypeMappingRegistryImpl(true); 98 TypeMapping tm = tmr 99 .getOrMakeTypeMapping(sd.getUse() == Use.ENCODED ? "http://schemas.xmlsoap.org/soap/encoding/" : ""); 101 sd.setTypeMappingRegistry(tmr); 102 sd.setTypeMapping(tm); 103 104 112 sd.getOperations(); 113 114 for (BeehiveWsMethodMetadata meth : wsm.getMethods()) { 116 String operationName = meth.getWmOperationName(); 117 if (null != operationName && 0 < operationName.length()) { 118 OperationDesc od = sd.getOperationByName(meth 120 .getJavaMethodName()); 121 od.setElementQName(new QName (targetNamespace, operationName)); 122 od.setName(operationName); 123 od.setSoapAction(meth.getWmAction()); 124 if (meth.isOneWay()) { 125 od.setMep(OperationType.ONE_WAY); 126 } else { 127 String namespace = "" ; 128 if( wsm.getSoapBinding().getStyle() == SOAPBinding.Style.DOCUMENT) namespace = meth.getWrTargetNamespace(); 130 od.setReturnQName(new QName (namespace, 131 meth.getWrName())); 132 final Class returnType = meth.getJavaReturnType(); 133 QName qn = configureTypeMapping(sd, returnType, meth 134 .getWrTargetNamespace()); 135 od.setReturnType(qn); 136 od.setReturnClass(returnType); 137 } 138 139 int pcnt = 0; 141 for (BeehiveWsParameterMetadata param : meth.getParams()) { 142 ParameterDesc pd = od.getParameter(pcnt++); 143 final Class paramType = param.getJavaType(); 144 145 if (pd.getTypeQName() == null) { QName typeQName = configureTypeMapping(sd, paramType, 149 param.getWpTargetNamespace()); 150 156 pd.setTypeQName(typeQName); 157 } 158 159 String namespace = "" ; 161 if( wsm.getSoapBinding().getStyle() == SOAPBinding.Style.DOCUMENT) namespace = param.getWpTargetNamespace(); 163 QName paramQName = new QName (namespace, 164 param.getWpName()); 165 pd.setQName(paramQName); 166 167 final boolean header = param.isWpHeader(); 169 final WebParam.Mode mode = param.getWpMode(); 170 switch (mode) { 171 case IN: 172 pd.setMode(ParameterDesc.IN); 173 pd.setInHeader(header); 174 pd.setOutHeader(false); 175 break; 176 case OUT: 177 pd.setMode(ParameterDesc.OUT); 178 pd.setInHeader(false); 179 pd.setOutHeader(header); 180 break; 181 case INOUT: 182 pd.setMode(ParameterDesc.INOUT); 183 pd.setInHeader(header); 184 pd.setOutHeader(header); 185 break; 186 default: 187 throw new IllegalArgumentException ( 188 "Illegal value for WebParam.Mode: " + mode); 189 } 190 191 pd.setJavaType(paramType); 193 } 194 195 Method javaMethod = od.getMethod(); 197 for (Class thrown : javaMethod.getExceptionTypes()) { 198 FaultDesc fd = od.getFaultByClass(thrown); 199 if (null == fd) { 200 logger 201 .info("Exception: " 202 + thrown.getCanonicalName() 203 + " is not picked up by the Axis, only non Remote and Application Specific exceptions are registed in Axis. This is not a fatal error."); 204 continue; 205 } 206 QName qname = configureTypeMapping(sd, thrown, meth 207 .getWrTargetNamespace()); 208 fd.setXmlType(qname); 209 fd.setQName(qname); 210 fd.setComplex(true); 211 } 212 } 213 } 214 return sd; 215 } 216 217 224 private static boolean isActivationEnabled() { 225 return null != getDataHandlerClass() && null != getMultipartClass(); 226 } 227 228 234 private static Class getDataHandlerClass() { 235 try { 236 return AxisHook.class.getClassLoader().loadClass( 237 "javax.activation.DataHandler"); 238 } catch (ClassNotFoundException e) { 239 } 241 return null; 242 } 243 244 250 private static Class getMultipartClass() { 251 try { 252 return AxisHook.class.getClassLoader().loadClass( 253 "javax.mail.internet.MimeMultipart"); 254 } catch (ClassNotFoundException e) { 255 } 257 return null; 258 } 259 260 private static QName configureTypeMapping(ServiceDesc desc, Class type, 261 String defaultNameSpace) throws InvalidTypeMappingException { 262 try { 263 if (Void.TYPE.equals(type)) 264 return null; 265 266 if (AxisTypeMappingMetaData.isBuiltInType(type)) 270 return AxisTypeMappingMetaData.getBuiltInTypeQname(type); 271 272 if(Holder .class.isAssignableFrom(type )) { 273 type = TypeRegistrar.getHoldersValueClass(type); 274 } 276 277 TypeMapping tm = desc.getTypeMapping(); 279 297 BindingLookupService lookupService = new SystemTypeLookupService(); QName q = lookupService.class2qname(type, defaultNameSpace); 299 300 301 if (type.isArray()) { 302 306 if (!tm.isRegistered(type, q) && desc.getStyle() == Style.RPC 307 && desc.getUse() == Use.ENCODED) { 308 tm.register(type, q, new ArraySerializerFactory(type, q), 309 new ArrayDeserializerFactory()); 310 } 311 QName qcomp = configureTypeMapping(desc, type 312 .getComponentType(), defaultNameSpace); 313 if (desc.getUse() == Use.LITERAL) { 314 q = qcomp; 315 } 316 } else if (!tm.isRegistered(type, q)) { 317 if (XmlObject.class.isAssignableFrom(type)) { 318 q = XmlBeans.typeForClass(type).getName(); 319 tm.register(type, q, new XmlBeanSerializerFactory(type, q), 320 new XmlBeanDeserializerFactory(type, q)); 321 } 322 326 else if (isActivationEnabled() 327 && (java.awt.Image .class.isAssignableFrom(type) 328 || getMultipartClass().isAssignableFrom(type) || getDataHandlerClass() 329 .isAssignableFrom(type))) { 330 try { 331 336 ClassLoader cl = AxisHook.class.getClassLoader(); 337 Class <SerializerFactory> sfClass = (Class <SerializerFactory>) cl 348 .loadClass("org.apache.axis.encoding.ser.JAFDataHandlerSerializerFactory"); 349 Class <DeserializerFactory> dsfClass = (Class <DeserializerFactory>) cl 350 .loadClass("org.apache.axis.encoding.ser.JAFDataHandlerDeserializerFactory"); 351 Constructor <SerializerFactory> sfCon = sfClass 352 .getConstructor(Class .class, QName .class); 353 Constructor <DeserializerFactory> dsfCon = dsfClass 354 .getConstructor(Class .class, QName .class); 355 SerializerFactory sf = sfCon.newInstance(type, q); 356 DeserializerFactory dsf = dsfCon.newInstance(type, q); 357 tm.register(type, q, sf, dsf); 358 } catch (Exception e) { 359 363 e.printStackTrace(); 364 } 365 } else if (!Remote .class.isAssignableFrom(type) 366 375 && !File .class.isAssignableFrom(type)) { 376 TypeDesc td = TypeDesc.getTypeDescForClass(type); 377 378 if (td != null 381 && !td.getXmlType().getNamespaceURI().equals( 382 q.getNamespaceURI())) { 383 td = null; 384 } 385 TypeDesc superTd = null; 386 BeanPropertyDescriptor[] superPd = null; 387 if (null == td) { 390 td = new TypeDesc(type); Class supa = type.getSuperclass(); 396 if ((supa != null) && (supa != java.lang.Object .class) 397 && (supa != java.lang.Exception .class) 398 && (supa != java.lang.Throwable .class) 399 && (supa != java.rmi.RemoteException .class) 400 && (supa != org.apache.axis.AxisFault.class)) { 401 configureTypeMapping(desc, supa, defaultNameSpace); 402 } 403 superTd = TypeDesc.getTypeDescForClass(supa); 406 if (superTd != null) { 409 superPd = superTd.getPropertyDescriptors(); } 418 td.setXmlType(q); 419 TypeDesc.registerTypeDescForClass(type, td); 420 } else { 426 td = null; } 429 446 tm.register(type, q, new EnhancedBeanSerializerFactory( 451 type, q, td), 452 458 new EnhancedBeanDeSerializerFactory(type, q, td)); 459 460 Map serProps = BeanDeserializerFactory.getProperties(type, 466 null); for (BeanPropertyDescriptor beanProps : (Collection <BeanPropertyDescriptor>) serProps 468 .values()) { 469 Class subType = beanProps.getType(); 470 if (!(subType.isPrimitive() 473 || subType.getName().startsWith("java.") || subType 474 .getName().startsWith("javax."))) { 475 configureTypeMapping(desc, subType, 476 defaultNameSpace); } 480 481 if (td != null) { String ns = q.getNamespaceURI(); if (superTd != null && superPd != null) { for (int j = 0; j < superPd.length; j++) { 499 if (beanProps.getName().equals( 500 superPd[j].getName())) { 501 ns = superTd.getXmlType() 502 .getNamespaceURI(); 503 break; 504 } 505 } 506 } 507 FieldDesc fd = new ElementDesc(); 508 fd.setJavaType(subType); 509 fd.setFieldName(beanProps.getName()); 510 fd.setXmlName(new QName (ns, beanProps.getName())); 511 fd.setXmlType(tm.getTypeQName(subType)); 514 ((ElementDesc) fd).setNillable(true); 515 td.addFieldDesc(fd); 520 } 521 } 522 } else { 523 throw new InvalidTypeMappingException("failed to register " 524 + type.getName() 525 + " as a valid web service datatype," 526 + " consider using a custom type mapping"); 527 } 528 } 529 return q; 530 531 } catch (RuntimeException e) { 532 logger.error("Error in type registeration", e); 533 e.printStackTrace(); 534 throw e; 535 } 536 } 537 538 private static QName generateQName(Class type, ServiceDesc desc) { 539 String namespace = Namespaces.makeNamespace(type.getName()); 540 if (namespace == null || namespace.endsWith("DefaultNamespace")) { 541 namespace = desc.getDefaultNamespace(); 542 } 543 return new QName (namespace, Types.getLocalNameFromFullName(type 544 .getName())); 545 } 546 547 protected static void configureSoapBinding(ServiceDesc sd, 548 BeehiveWsSOAPBindingInfo sbi) { 549 javax.jws.soap.SOAPBinding.Style style = javax.jws.soap.SOAPBinding.Style.DOCUMENT; 550 javax.jws.soap.SOAPBinding.Use use = javax.jws.soap.SOAPBinding.Use.LITERAL; 551 javax.jws.soap.SOAPBinding.ParameterStyle paramStyle = javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED; 552 if (sbi != null) { 553 style = sbi.getStyle(); 554 use = sbi.getUse(); 555 paramStyle = sbi.getParameterStyle(); 556 } 557 if (style == javax.jws.soap.SOAPBinding.Style.RPC) { 558 sd.setStyle(Style.RPC); 559 if (use == javax.jws.soap.SOAPBinding.Use.ENCODED) { 560 sd.setUse(Use.ENCODED); 561 } else { 562 sd.setUse(Use.LITERAL); 563 } 564 } else { 565 568 sd.setUse(Use.LITERAL); 569 570 if (paramStyle == javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED) { 572 sd.setStyle(Style.WRAPPED); 573 } else { 574 sd.setStyle(Style.DOCUMENT); 576 } 577 } 578 } 579 } 580 581 587 588 class EnhancedBeanSerializerFactory extends BeanSerializerFactory { 589 public EnhancedBeanSerializerFactory(Class javaType, QName xmlType, 590 TypeDesc typeDesc) { 591 super(javaType, xmlType); 592 593 this.typeDesc = typeDesc; 594 595 if (typeDesc != null) { 596 propertyDescriptor = typeDesc.getPropertyDescriptors(); 597 } else { 598 propertyDescriptor = BeanUtils.getPd(javaType, null); 599 } 600 } 601 } 602 603 class EnhancedBeanDeSerializerFactory extends BeanDeserializerFactory { 604 public EnhancedBeanDeSerializerFactory(Class javaType, QName xmlType, 605 TypeDesc typeDesc) { 606 super(javaType, xmlType); 607 608 this.typeDesc = typeDesc; 609 propertyMap = getProperties(javaType, typeDesc); 610 } 611 612 } 613 | Popular Tags |