1 55 56 package org.jboss.axis.client; 57 58 import org.jboss.axis.AxisFault; 59 import org.jboss.axis.Constants; 60 import org.jboss.axis.description.OperationDesc; 61 import org.jboss.axis.description.ParameterDesc; 62 import org.jboss.axis.enums.Style; 63 import org.jboss.axis.enums.Use; 64 import org.jboss.axis.utils.JavaUtils; 65 import org.jboss.logging.Logger; 66 67 import javax.activation.DataHandler ; 68 import javax.xml.namespace.QName ; 69 import javax.xml.rpc.ServiceException ; 70 import javax.xml.rpc.holders.Holder ; 71 import java.lang.reflect.Constructor ; 72 import java.lang.reflect.InvocationHandler ; 73 import java.lang.reflect.Method ; 74 import java.util.ArrayList ; 75 import java.util.Map ; 76 77 86 public class AxisClientProxy implements InvocationHandler 87 { 88 89 private static Logger log = Logger.getLogger(AxisClientProxy.class.getName()); 90 91 private Call call; 92 private QName portName; 93 94 99 AxisClientProxy(Call call, QName portName) 100 { 101 this.call = call; 102 this.portName = portName; } 104 105 106 116 private Object [] proxyParams2CallParams(Object [] proxyParams) 117 throws JavaUtils.HolderException, ServiceException 118 { 119 ArrayList callParams = new ArrayList (); 120 121 OperationDesc operationDesc = call.getOperation(); 122 if (operationDesc == null || proxyParams == null) 123 { 124 return proxyParams; 127 } 128 129 boolean isDocumentLiteral = Style.DOCUMENT.equals(operationDesc.getStyle()) && Use.LITERAL.equals(operationDesc.getUse()); 132 if (isDocumentLiteral) 133 { 134 int proxyIndex = 0; 135 ArrayList opParams = operationDesc.getParameters(); 136 for (int i = 0; i < opParams.size(); i++) 137 { 138 ParameterDesc parameterDesc = (ParameterDesc)opParams.get(i); 139 Class javaType = parameterDesc.getJavaType(); 140 141 if (javaType == null || proxyParams[proxyIndex] == null) 143 { 144 callParams.add(proxyParams[proxyIndex++]); 145 continue; 146 } 147 148 Class proxyType = proxyParams[proxyIndex].getClass(); 150 if (javaType.isAssignableFrom(proxyType)) 151 { 152 callParams.add(proxyParams[proxyIndex++]); 153 continue; 154 } 155 156 if (JavaUtils.isConvertable(proxyType, javaType)) 158 { 159 Object param = JavaUtils.convert(proxyParams[proxyIndex++], javaType); 160 callParams.add(param); 161 continue; 162 } 163 164 boolean ctorFound = false; 166 Constructor [] ctors = javaType.getConstructors(); 167 for (int j = 0; j < ctors.length; j++) 168 { 169 boolean paramsMatch = true; 170 171 Constructor ctor = ctors[j]; 173 Class [] ctorTypes = ctor.getParameterTypes(); 174 if (ctorTypes.length > 0) 175 { 176 Object [] ctorVals = new Object [ctorTypes.length]; 177 for (int k = 0; paramsMatch && k < ctorTypes.length; k++) 178 { 179 if (ctorTypes[k].isAssignableFrom(proxyParams[proxyIndex + k].getClass())) 180 ctorVals[k] = proxyParams[proxyIndex + k]; 181 else 182 paramsMatch = false; 183 } 184 185 if (paramsMatch) 186 { 187 try 188 { 189 Object inst = ctor.newInstance(ctorVals); 190 proxyIndex += ctorVals.length; 191 callParams.add(inst); 192 ctorFound = true; 193 break; 194 } 195 catch (Exception e) 196 { 197 throw new ServiceException ("Cannot map proxy params to: " + javaType); 198 } 199 } 200 } 201 } 202 203 if (ctorFound == false) 205 callParams.add(proxyParams[proxyIndex++]); 206 } 207 } 208 209 else 211 { 212 for (int i = 0; proxyParams != null && i < proxyParams.length; i++) 213 { 214 Object param = proxyParams[i]; 215 ParameterDesc paramDesc = operationDesc.getParameter(i); 216 if (paramDesc == null) 217 throw new ServiceException ("Cannot obtain parameter " + i + " for: " + operationDesc); 218 219 if (paramDesc.getMode() == ParameterDesc.INOUT) 220 { 221 callParams.add(JavaUtils.getHolderValue((Holder )param)); 222 } 223 else if (paramDesc.getMode() == ParameterDesc.IN) 224 { 225 callParams.add(param); 226 } 227 } 228 } 229 230 return callParams.toArray(); 231 } 232 233 237 private void proxyReturn2CallReturn(Class proxyReturn) 238 { 239 240 OperationDesc operationDesc = call.getOperation(); 241 if (operationDesc != null) 242 { 243 Class operationReturn = operationDesc.getReturnClass(); 244 if (proxyReturn != null && operationReturn != null) 245 { 246 if (proxyReturn.equals(DataHandler .class)) 249 { 250 operationDesc.setReturnClass(DataHandler .class); 251 operationDesc.setReturnType(Constants.MIME_DATA_HANDLER); 252 } 253 254 boolean isConvertible = JavaUtils.isConvertable(operationReturn, proxyReturn); 255 if (isConvertible == false) 256 isConvertible = getDocLitResultWrapper(operationReturn, proxyReturn) != null; 257 258 if (isConvertible == false) 259 { 260 log.debug("Fixing return class: " + operationReturn + " -> " + proxyReturn); 261 operationDesc.setReturnClass(proxyReturn); 262 } 263 } 264 265 if (proxyReturn == null && operationReturn != null) 266 { 267 log.debug("Forcing return class to null: " + operationReturn); 268 operationDesc.setReturnClass(null); 269 } 270 } 271 } 272 273 276 private Method getDocLitResultWrapper(Class callReturn, Class proxyReturn) 277 { 278 Method getter = null; 279 OperationDesc operationDesc = call.getOperation(); 280 281 boolean isDocumentLiteral = Style.DOCUMENT.equals(operationDesc.getStyle()) && Use.LITERAL.equals(operationDesc.getUse()); 283 if (isDocumentLiteral) 284 { 285 Method [] methods = callReturn.getMethods(); 286 for (int i = 0; getter == null && i < methods.length; i++) 287 { 288 Method method = methods[i]; 289 if (method.getName().startsWith("get") && method.getParameterTypes().length == 0 && proxyReturn.isAssignableFrom(method.getReturnType())) 290 { 291 log.debug("Trying to unwrap proxy return with: " + method); 292 getter = method; 293 } 294 } 295 } 296 297 return getter; 298 } 299 300 305 private void callOutputParams2proxyParams(Object [] proxyParams) 306 throws JavaUtils.HolderException 307 { 308 OperationDesc operationDesc = call.getOperation(); 309 if (operationDesc == null || proxyParams == null) 310 { 311 return; 314 } 315 316 Map outputParams = call.getOutputParams(); 317 318 for (int i = 0; i < operationDesc.getNumParams(); i++) 319 { 320 Object param = proxyParams[i]; 321 ParameterDesc paramDesc = operationDesc.getParameter(i); 322 if (paramDesc.getMode() != ParameterDesc.IN) 323 { 324 Object value = outputParams.get(paramDesc.getQName()); 325 326 if (Holder .class.isAssignableFrom(value.getClass())) 328 value = JavaUtils.getHolderValue(value); 329 330 JavaUtils.setHolderValue((Holder )param, value); 331 } 332 } 333 } 334 335 336 339 public Object invoke(Object o, Method method, Object [] objects) 340 throws Throwable 341 { 342 try 343 { 344 if (method.getName().equals("_setProperty")) 345 { 346 call.setProperty((String )objects[0], objects[1]); 347 return null; 348 } 349 else if (method.getName().equals("_getProperty")) 350 { 351 return call.getProperty((String )objects[0]); 352 353 } 354 else if (method.getName().equals("hashCode")) 355 { 356 return new Integer (call.hashCode()); 357 358 } 359 else if (method.getName().equals("toString")) 360 { 361 return call.toString(); 362 363 } 364 else if (method.getName().equals("equals")) 365 { 366 return new Boolean (o == objects[0]); 367 368 } 369 else 370 { 371 Object outValue; 372 Object [] paramsCall; 373 374 if ((call.getTargetEndpointAddress() != null) && (call.getPortName() != null)) 375 { 376 call.setOperation(method.getName()); 379 paramsCall = proxyParams2CallParams(objects); 380 proxyReturn2CallReturn(method.getReturnType()); 381 outValue = call.invoke(paramsCall); 382 } 383 else if (portName != null) 384 { 385 call.setOperation(portName, method.getName()); 388 paramsCall = proxyParams2CallParams(objects); 389 proxyReturn2CallReturn(method.getReturnType()); 390 outValue = call.invoke(paramsCall); 391 } 392 else 393 { 394 paramsCall = objects; 396 proxyReturn2CallReturn(method.getReturnType()); 397 outValue = call.invoke(method.getName(), paramsCall); 398 } 399 400 callOutputParams2proxyParams(objects); 401 outValue = callReturn2ProxyReturn(outValue, method.getReturnType()); 402 403 return outValue; 404 } 405 } 406 catch (AxisFault af) 407 { 408 if (af.detail != null) 409 { 410 throw af.detail; 411 } 412 throw af; 413 } 414 } 415 416 419 private Object callReturn2ProxyReturn(Object callReturn, Class proxyReturnType) 420 { 421 if (callReturn == null) 423 return callReturn; 424 425 if (JavaUtils.isConvertable(callReturn, proxyReturnType)) 427 return JavaUtils.convert(callReturn, proxyReturnType); 428 429 if (callReturn instanceof ArrayList ) 431 return convertArrayList(callReturn); 432 433 Class callReturnType = callReturn.getClass(); 434 Method docLitResultWrapper = getDocLitResultWrapper(callReturnType, proxyReturnType); 435 if (docLitResultWrapper != null) 436 { 437 try 438 { 439 Object proxyReturn = docLitResultWrapper.invoke(callReturn, new Object []{}); 440 return proxyReturn; 441 } 442 catch (Exception e) 443 { 444 log.error("Cannot unwrap call return", e); 445 } 446 } 447 448 log.warn("Cannot convert call return " + callReturnType.getName() + " to: " + proxyReturnType.getName()); 449 return callReturn; 450 } 451 452 private Object convertArrayList(Object outValue) 453 { 454 Object value = ((ArrayList )outValue).toArray(); 455 456 if (value.getClass().isArray()) 458 { 459 if (!value.getClass().getComponentType().isPrimitive()) 460 { 461 int len = java.lang.reflect.Array.getLength(value); 462 Class type = null; 463 for (int x = 0; x < len; x++) 464 { 465 Object o = java.lang.reflect.Array.get(value, x); 466 if (o != null) 467 { 468 if (type == null) 469 { 470 type = o.getClass(); 471 } 472 else 473 { 474 if (!type.getName().equals(o.getClass().getName())) 475 { 476 type = null; 477 break; 478 } 479 } 480 } 481 } 482 if (type != null) 484 { 485 Object convertedArray = java.lang.reflect.Array.newInstance(type, len); 486 System.arraycopy(value, 0, convertedArray, 0, len); 487 value = convertedArray; 488 } 489 } 490 } 491 492 return value; 493 } 494 495 500 public Call getCall() 501 { 502 return call; 503 } 504 } 505 | Popular Tags |