1 29 30 package com.caucho.soap.skeleton; 31 32 import com.caucho.jaxb.JAXBContextImpl; 33 import com.caucho.jaxb.skeleton.Property; 34 35 import com.caucho.soap.wsdl.SOAPOperation; 36 import com.caucho.soap.wsdl.WSDLBindingOperation; 37 import com.caucho.soap.wsdl.WSDLBindingOperationMessage; 38 import com.caucho.soap.wsdl.WSDLMessage; 39 import com.caucho.soap.wsdl.WSDLOperation; 40 import com.caucho.soap.wsdl.WSDLOperationFault; 41 import com.caucho.util.L10N; 42 43 import javax.jws.WebMethod; 44 import javax.jws.WebParam; 45 import javax.xml.bind.JAXBException; 46 import javax.xml.bind.Marshaller; 47 import javax.xml.bind.Unmarshaller; 48 import javax.xml.namespace.QName ; 49 import javax.xml.stream.XMLInputFactory; 50 import javax.xml.stream.XMLOutputFactory; 51 import javax.xml.stream.XMLStreamException; 52 import javax.xml.stream.XMLStreamReader; 53 import javax.xml.stream.XMLStreamWriter; 54 import javax.xml.ws.Holder; 55 import javax.xml.ws.WebServiceException; 56 import java.io.IOException ; 57 import java.io.InputStream ; 58 import java.io.OutputStream ; 59 import java.lang.reflect.Method ; 60 import java.lang.reflect.ParameterizedType ; 61 import java.lang.reflect.Type ; 62 import java.net.HttpURLConnection ; 63 import java.net.MalformedURLException ; 64 import java.net.URL ; 65 import java.net.URLConnection ; 66 import java.util.ArrayList ; 67 import java.util.LinkedHashMap ; 68 import java.util.Map ; 69 import java.util.logging.Logger ; 70 71 74 public abstract class AbstractAction { 75 private final static Logger log = 76 Logger.getLogger(AbstractAction.class.getName()); 77 private static final L10N L = new L10N(AbstractAction.class); 78 79 private static final String TARGET_NAMESPACE_PREFIX = "tns"; 80 protected static final String SOAP_ENCODING_STYLE 81 = "http://schemas.xmlsoap.org/soap/encoding/"; 82 83 protected final XMLOutputFactory _xmlOutputFactory 84 = XMLOutputFactory.newInstance(); 85 protected final XMLInputFactory _xmlInputFactory 86 = XMLInputFactory.newInstance(); 87 88 protected final Method _method; 89 protected final int _arity; 90 91 protected String _responseName; 92 protected String _operationName; 93 protected QName _requestName; 94 protected QName _resultName; 95 96 protected final LinkedHashMap <String ,ParameterMarshal> _bodyArguments 98 = new LinkedHashMap <String ,ParameterMarshal>(); 99 protected ParameterMarshal[] _bodyArgs; 100 101 protected final LinkedHashMap <String ,ParameterMarshal> _headerArguments 102 = new LinkedHashMap <String ,ParameterMarshal>(); 103 104 protected ParameterMarshal _retMarshal; 105 106 protected int _headerOutputs; 107 protected int _bodyOutputs; 108 109 protected final JAXBContextImpl _jaxbContext; 110 protected final String _targetNamespace; 111 112 116 protected final WSDLMessage _inputMessage = new WSDLMessage(); 117 protected final WSDLMessage _outputMessage = new WSDLMessage(); 118 protected final ArrayList <WSDLMessage> _faultMessages 119 = new ArrayList <WSDLMessage>(); 120 121 protected final WSDLOperation _wsdlOperation = new WSDLOperation(); 122 protected final ArrayList <WSDLOperationFault> _wsdlFaults 123 = new ArrayList <WSDLOperationFault>(); 124 125 protected final WSDLBindingOperation _wsdlBindingOperation 126 = new WSDLBindingOperation(); 127 128 protected AbstractAction(Method method, JAXBContextImpl jaxbContext, 129 String targetNamespace) 130 throws JAXBException, WebServiceException 131 { 132 _method = method; 133 _arity = _method.getParameterTypes().length; 134 _jaxbContext = jaxbContext; 135 _targetNamespace = targetNamespace; 137 _operationName = getWebMethodName(method); 140 _responseName = _operationName + "Response"; 141 142 _inputMessage.setName(_operationName); 143 _outputMessage.setName(_responseName); 144 145 _wsdlOperation.setName(_operationName); 146 _wsdlBindingOperation.setName(_operationName); 147 148 150 _wsdlBindingOperation.setInput(new WSDLBindingOperationMessage()); 151 _wsdlBindingOperation.setOutput(new WSDLBindingOperationMessage()); 152 153 SOAPOperation soapOperation = new SOAPOperation(); 155 soapOperation.setSoapAction(""); _wsdlBindingOperation.addAny(soapOperation); 157 } 158 159 public static AbstractAction createAction(Method method, 160 JAXBContextImpl jaxbContext, 161 String targetNamespace, 162 Marshaller marshaller, 163 Unmarshaller unmarshaller) 164 throws JAXBException, WebServiceException 165 { 166 192 Class cl = method.getDeclaringClass(); 193 javax.jws.soap.SOAPBinding soapBinding = null; 194 195 if (cl.isAnnotationPresent(javax.jws.soap.SOAPBinding.class)) { 196 soapBinding = (javax.jws.soap.SOAPBinding) 197 cl.getAnnotation(javax.jws.soap.SOAPBinding.class); 198 } 199 200 if (method.isAnnotationPresent(javax.jws.soap.SOAPBinding.class)) { 201 soapBinding = (javax.jws.soap.SOAPBinding) 202 method.getAnnotation(javax.jws.soap.SOAPBinding.class); 203 } 204 205 if (soapBinding == null) 207 return new DocumentWrappedAction(method, jaxbContext, targetNamespace, 208 marshaller, unmarshaller); 209 210 if (soapBinding.use() == javax.jws.soap.SOAPBinding.Use.ENCODED) 211 throw new UnsupportedOperationException (L.l("SOAP encoded style is not supported by JAX-WS")); 212 213 if (soapBinding.style() == javax.jws.soap.SOAPBinding.Style.DOCUMENT) { 214 if (soapBinding.parameterStyle() == 215 javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED) 216 return new DocumentWrappedAction(method, jaxbContext, targetNamespace, 217 marshaller, unmarshaller); 218 else { 219 return new DocumentBareAction(method, jaxbContext, targetNamespace, 220 marshaller, unmarshaller); 221 } 222 } 223 else { 224 if (soapBinding.parameterStyle() != 225 javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED) 226 throw new UnsupportedOperationException (L.l("SOAP RPC bare style not supported")); 227 228 return new RpcAction(method, jaxbContext, targetNamespace, 229 marshaller, unmarshaller); 230 } 231 } 232 233 236 public Object invoke(String url, Object [] args) 237 throws IOException , XMLStreamException, MalformedURLException , JAXBException 238 { 239 URL urlObject = new URL (url); 240 URLConnection connection = urlObject.openConnection(); 241 242 if (! (connection instanceof HttpURLConnection )) 244 return null; 245 246 HttpURLConnection httpConnection = (HttpURLConnection ) connection; 247 248 try { 249 253 httpConnection.setRequestMethod("POST"); 254 httpConnection.setDoInput(true); 255 httpConnection.setDoOutput(true); 256 257 OutputStream httpOut = httpConnection.getOutputStream(); 258 XMLStreamWriter out = _xmlOutputFactory.createXMLStreamWriter(httpOut); 259 260 writeRequest(out, args); 261 out.flush(); 262 263 267 if (httpConnection.getResponseCode() != 200) 268 return null; 270 InputStream httpIn = httpConnection.getInputStream(); 271 XMLStreamReader in = _xmlInputFactory.createXMLStreamReader(httpIn); 272 273 Object ret = readResponse(in, args); 274 275 return ret; 276 } 277 finally { 278 if (httpConnection != null) 279 httpConnection.disconnect(); 280 } 281 } 282 283 protected void writeRequest(XMLStreamWriter out, Object []args) 284 throws IOException , XMLStreamException, JAXBException 285 { 286 out.writeStartDocument(); 287 out.writeStartElement(Skeleton.SOAP_ENVELOPE_PREFIX, 288 "Envelope", 289 Skeleton.SOAP_ENVELOPE); 290 out.writeNamespace(Skeleton.SOAP_ENVELOPE_PREFIX, Skeleton.SOAP_ENVELOPE); 291 292 out.writeStartElement(Skeleton.SOAP_ENVELOPE_PREFIX, 293 "Header", 294 Skeleton.SOAP_ENVELOPE); 295 296 for (ParameterMarshal marshal : _headerArguments.values()) 297 marshal.serializeCall(out, args); 298 299 out.writeEndElement(); 301 out.writeStartElement(Skeleton.SOAP_ENVELOPE_PREFIX, 302 "Body", 303 Skeleton.SOAP_ENVELOPE); 304 305 out.writeStartElement(TARGET_NAMESPACE_PREFIX, 306 _operationName, 307 _targetNamespace); 308 out.writeNamespace(TARGET_NAMESPACE_PREFIX, 309 _targetNamespace); 310 311 for (int i = 0; i < _bodyArgs.length; i++) 312 _bodyArgs[i].serializeCall(out, args); 313 314 out.writeEndElement(); 316 out.writeEndElement(); out.writeEndElement(); } 319 320 protected Object readResponse(XMLStreamReader in, Object []args) 321 throws IOException , XMLStreamException, JAXBException 322 { 323 Object ret = null; 324 325 in.nextTag(); 326 327 if (! "Envelope".equals(in.getName().getLocalPart())) 328 throw new IOException ("expected Envelope at " + in.getName()); 329 330 if (_headerOutputs > 0) { 332 in.nextTag(); 333 334 if (! "Header".equals(in.getName().getLocalPart())) 335 throw new IOException ("expected <Header>"); 336 337 for (int i = 0; i < _headerOutputs; i++) { 338 String tagName = in.getLocalName(); 339 340 ParameterMarshal marshal = _headerArguments.get(tagName); 341 342 if (marshal == null) 343 throw new IOException (L.l("Unknown output in header <{0}>", tagName)); 344 345 Object value = marshal.deserializeReply(in); 346 347 if (marshal.getArg() < 0) 348 ret = value; 349 else 350 ((Holder) args[marshal.getArg()]).value = value; 351 352 if (i + 1 < _headerOutputs) 353 in.nextTag(); 354 } 355 356 if (in.nextTag() != in.END_ELEMENT) 357 throw new IOException ("expected </Header>"); 358 } 359 360 in.nextTag(); 362 if (! "Body".equals(in.getName().getLocalPart())) 363 throw new IOException ("expected Body"); 364 365 if (_bodyOutputs > 0) { 367 for (int i = 0; i < _headerOutputs; i++) { 368 String tagName = in.getLocalName(); 369 370 ParameterMarshal marshal = _headerArguments.get(tagName); 371 372 if (marshal == null) 373 throw new IOException (L.l("Unknown output in header <{0}>", tagName)); 374 375 Object value = marshal.deserializeReply(in); 376 377 if (marshal._arg < 0) 378 ret = value; 379 else 380 ((Holder) args[marshal.getArg()]).value = value; 381 382 if (i + 1 < _headerOutputs) 383 in.nextTag(); 384 } 385 } 386 387 if (in.nextTag() != in.END_ELEMENT) 388 throw new IOException (L.l("expected </Body> at <{0}>", 389 in.getName().getLocalPart())); 390 391 392 if (in.nextTag() != in.END_ELEMENT) 393 throw new IOException (L.l("expected </Envelope> at {0}", 394 in.getName().getLocalPart())); 395 396 return ret; 397 } 398 399 402 public void invoke(Object service, XMLStreamReader in, XMLStreamWriter out) 403 throws IOException , XMLStreamException, Throwable 404 { 405 } 406 407 410 public WSDLMessage getInputMessage() 411 { 412 return _inputMessage; 413 } 414 415 418 public WSDLMessage getOutputMessage() 419 { 420 return _outputMessage; 421 } 422 423 public WSDLOperation getOperation() 424 { 425 return _wsdlOperation; 426 } 427 428 public WSDLBindingOperation getBindingOperation() 429 { 430 return _wsdlBindingOperation; 431 } 432 433 public boolean hasHeaderInput() 434 { 435 return false; 436 } 437 438 public int getArity() 439 { 440 return _arity; 441 } 442 443 protected static Class getHolderValueType(Type holder) 444 { 445 Type holderParams[] = ((ParameterizedType ) holder).getActualTypeArguments(); 447 return (Class ) holderParams[0]; 448 } 449 450 public static String getWebMethodName(Method method) 451 { 452 String name = method.getName(); 453 454 WebMethod webMethod = (WebMethod) method.getAnnotation(WebMethod.class); 455 456 if (webMethod != null && ! "".equals(webMethod.operationName())) 457 name = webMethod.operationName(); 458 459 return name; 460 } 461 } 462 | Popular Tags |