1 29 30 package com.caucho.soap.skeleton; 31 32 import com.caucho.jaxb.JAXBUtil; 33 import com.caucho.soap.wsdl.*; 34 import com.caucho.util.L10N; 35 import com.caucho.xml.XmlPrinter; 36 37 import org.w3c.dom.Node ; 38 39 import javax.jws.WebService; 40 import javax.xml.bind.JAXBContext; 41 import javax.xml.bind.JAXBException; 42 import javax.xml.bind.Marshaller; 43 import javax.xml.bind.PropertyException; 44 import javax.xml.namespace.QName ; 45 import javax.xml.stream.XMLStreamException; 46 import javax.xml.stream.XMLStreamReader; 47 import javax.xml.stream.XMLStreamWriter; 48 import javax.xml.transform.dom.DOMResult ; 49 import javax.xml.ws.WebServiceException; 50 import java.io.File ; 51 import java.io.FileOutputStream ; 52 import java.io.IOException ; 53 import java.io.OutputStream ; 54 import java.io.Writer ; 55 import java.lang.reflect.Method ; 56 import java.net.MalformedURLException ; 57 import java.util.HashMap ; 58 import java.util.StringTokenizer ; 59 import java.util.logging.Logger ; 60 61 64 public class DirectSkeleton extends Skeleton { 65 private static final Logger log = 66 Logger.getLogger(DirectSkeleton.class.getName()); 67 public static final L10N L = new L10N(DirectSkeleton.class); 68 69 private JAXBContext _context; 70 private Marshaller _marshaller; 71 private Node _wsdlNode; 72 73 private HashMap <String ,AbstractAction> _actionMap 74 = new HashMap <String ,AbstractAction>(); 75 76 private Class _api; 77 78 private String _namespace; 79 private String _name; 80 private String _typeName; 81 private String _portName; 82 private String _serviceName; 83 private String _wsdlLocation; 84 85 private final WSDLDefinitions _wsdl = new WSDLDefinitions(); 86 private final WSDLTypes _wsdlTypes = new WSDLTypes(); 87 private final WSDLPortType _wsdlPortType = new WSDLPortType(); 88 private final WSDLBinding _wsdlBinding = new WSDLBinding(); 89 private final WSDLService _wsdlService = new WSDLService(); 90 private final SOAPAddress _soapAddress = new SOAPAddress(); 91 92 public DirectSkeleton(Class type, String wsdlAddress) 93 { 94 WebService webService = (WebService) type.getAnnotation(WebService.class); 95 setNamespace(type); 96 97 _name = getWebServiceName(type); 98 _typeName = _name + "PortType"; 99 100 _serviceName = webService != null && ! webService.serviceName().equals("") 101 ? webService.serviceName() 102 : _name + "HttpBinding"; 103 104 _portName = 105 webService != null && ! webService.portName().equals("") 106 ? webService.portName() 107 : _name + "HttpPort"; 108 109 _wsdlLocation = 110 webService != null && ! webService.wsdlLocation().equals("") 111 ? webService.wsdlLocation() 112 : null; 113 114 _wsdl.setTargetNamespace(_namespace); 115 116 _wsdl.addDefinition(_wsdlTypes); 117 118 _wsdlPortType.setName(_typeName); 119 _wsdl.addDefinition(_wsdlPortType); 120 121 javax.jws.soap.SOAPBinding sbAnnotation = 122 (javax.jws.soap.SOAPBinding) 123 type.getAnnotation(javax.jws.soap.SOAPBinding.class); 124 125 com.caucho.soap.wsdl.SOAPBinding soapBinding = 126 new com.caucho.soap.wsdl.SOAPBinding(); 127 soapBinding.setTransport("http://schemas.xmlsoap.org/soap/http"); 128 129 if (sbAnnotation != null && 130 sbAnnotation.style() == javax.jws.soap.SOAPBinding.Style.RPC) 131 soapBinding.setStyle(SOAPStyleChoice.RPC); 132 else 133 soapBinding.setStyle(SOAPStyleChoice.DOCUMENT); 134 135 if (sbAnnotation != null && 136 sbAnnotation.use() == javax.jws.soap.SOAPBinding.Use.ENCODED) 137 throw new WebServiceException(L.l("Encoded SOAP style not supported by JAX-WS")); 138 139 _wsdlBinding.addAny(soapBinding); 140 _wsdlBinding.setName(_name + "Binding"); 141 _wsdlBinding.setType(new QName (_namespace, _typeName, "tns")); 142 143 _wsdl.addDefinition(_wsdlBinding); 144 145 _wsdlService.setName(_serviceName); 146 147 WSDLPort port = new WSDLPort(); 148 port.setName(_name + "Port"); 149 port.setBinding(new QName (_namespace, _name + "Binding", "tns")); 150 151 _soapAddress.setLocation(wsdlAddress); 152 port.addAny(_soapAddress); 153 154 _wsdlService.addPort(port); 155 156 _wsdl.addDefinition(_wsdlService); 157 } 158 159 public String getNamespace() 160 { 161 return _namespace; 162 } 163 164 private void setNamespace(Class type) 165 { 166 WebService webService = (WebService) type.getAnnotation(WebService.class); 167 168 if (webService != null && ! webService.targetNamespace().equals("")) 169 _namespace = webService.targetNamespace(); 170 else { 171 _namespace = null; 172 String packageName = type.getPackage().getName(); 173 StringTokenizer st = new StringTokenizer (packageName, "."); 174 175 while (st.hasMoreTokens()) { 176 if (_namespace == null) 177 _namespace = st.nextToken(); 178 else 179 _namespace = st.nextToken() + "." + _namespace; 180 } 181 182 _namespace = "http://"+_namespace+"/"; 183 } 184 } 185 186 static String getWebServiceName(Class type) 187 { 188 WebService webService = (WebService) type.getAnnotation(WebService.class); 189 190 if (webService != null && !webService.name().equals("")) 191 return webService.name(); 192 else 193 return JAXBUtil.classBasename(type); 194 } 195 196 public void addAction(String name, AbstractAction action) 197 { 198 _actionMap.put(name, action); 199 200 _wsdl.addDefinition(action.getInputMessage()); 201 _wsdl.addDefinition(action.getOutputMessage()); 202 203 _wsdlPortType.addOperation(action.getOperation()); 204 _wsdlBinding.addOperation(action.getBindingOperation()); 205 } 206 207 210 public Object invoke(Method method, String url, Object [] args) 211 throws IOException , XMLStreamException, MalformedURLException , JAXBException 212 { 213 String actionName = AbstractAction.getWebMethodName(method); 214 AbstractAction action = _actionMap.get(actionName); 215 216 if (action != null) 217 return action.invoke(url, args); 218 else if ("toString".equals(actionName)) 219 return "SoapStub[" + (_api != null ? _api.getName() : "") + "]"; 220 else 221 throw new RuntimeException ("no such method: " + actionName); 222 } 223 224 227 public void invoke(Object service, XMLStreamReader in, XMLStreamWriter out) 228 throws IOException , XMLStreamException, Throwable 229 { 230 in.nextTag(); 231 232 if (! "Envelope".equals(in.getName().getLocalPart())) 233 throw new IOException (L.l("expected Envelope at {0}", in.getName())); 234 235 in.nextTag(); 236 237 if ("Header".equals(in.getName().getLocalPart())) { 238 int depth = 1; 239 240 while (depth > 0) { 241 switch (in.nextTag()) { 242 case XMLStreamReader.START_ELEMENT: 243 depth++; 244 break; 245 case XMLStreamReader.END_ELEMENT: 246 depth--; 247 break; 248 } 249 } 250 251 in.nextTag(); 252 } 253 254 if (! "Body".equals(in.getName().getLocalPart())) 255 throw new IOException (L.l("expected Body at {0}", in.getName())); 256 257 in.nextTag(); 258 259 String actionName = in.getName().getLocalPart(); 260 in.nextTag(); 261 262 out.writeStartDocument(); 263 out.writeStartElement(SOAP_ENVELOPE_PREFIX, "Envelope", SOAP_ENVELOPE); 264 out.writeNamespace(SOAP_ENVELOPE_PREFIX, SOAP_ENVELOPE); 265 out.writeNamespace("xsd", XMLNS_XSD); 267 268 out.writeStartElement(SOAP_ENVELOPE_PREFIX, "Body", SOAP_ENVELOPE); 269 270 AbstractAction action = _actionMap.get(actionName); 271 272 if (action != null) 274 action.invoke(service, in, out); 275 else { 276 } 278 279 if (in.getEventType() != in.END_ELEMENT) 280 throw new IOException ("expected </" + actionName + ">, " + 281 "not event of type " + in.getEventType()); 282 else if (! actionName.equals(in.getLocalName())) 283 throw new IOException ("expected </" + actionName + ">, " + 284 "not </" + in.getLocalName() + ">"); 285 286 if (in.nextTag() != in.END_ELEMENT) 287 throw new IOException ("expected </Body>, got: " + in.getName()); 288 else if (! "Body".equals(in.getLocalName())) 289 throw new IOException ("expected </Body>, got: " + in.getName()); 290 296 297 out.writeEndElement(); out.writeEndElement(); } 300 301 private Node getWSDLNode() 302 throws JAXBException 303 { 304 if (_wsdlNode != null) 305 return _wsdlNode; 306 307 if (_context == null) 308 _context = JAXBContext.newInstance("com.caucho.soap.wsdl"); 309 310 if (_marshaller == null) { 311 _marshaller = _context.createMarshaller(); 312 313 try { 314 _marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 315 } 316 catch(PropertyException e) { 317 log.finer(L.l("Unable to set prefix mapper")); 319 } 320 } 321 322 DOMResult result = new DOMResult (); 323 _marshaller.marshal(_wsdl, result); 324 325 _wsdlNode = result.getNode(); 326 327 return _wsdlNode; 328 } 329 330 333 public Node getTypesNode() 334 throws JAXBException 335 { 336 Node wsdlNode = getWSDLNode(); 337 338 Node definitionsNode = wsdlNode.getFirstChild(); 339 340 if (definitionsNode == null || 342 ! "definitions".equals(definitionsNode.getNodeName())) 343 throw new JAXBException(L.l("Unable to attach types node")); 344 345 Node typesNode = definitionsNode.getFirstChild(); 346 347 if (typesNode == null || ! "types".equals(typesNode.getNodeName())) 348 throw new JAXBException(L.l("Unable to attach types node")); 349 350 return typesNode; 351 } 352 353 public void dumpWSDL(OutputStream w) 354 throws IOException , JAXBException 355 { 356 XmlPrinter printer = new XmlPrinter(w); 357 printer.setPrintDeclaration(true); 358 printer.printPrettyXml(getWSDLNode()); 359 } 360 361 public void dumpWSDL(Writer w) 362 throws IOException , JAXBException 363 { 364 XmlPrinter printer = new XmlPrinter(w); 365 printer.setPrintDeclaration(true); 366 printer.printPrettyXml(getWSDLNode()); 367 } 368 369 373 public void dumpWSDL(String dir) 374 throws IOException , JAXBException 375 { 376 File child = new File (dir, _serviceName + ".wsdl"); 377 dumpWSDL(new FileOutputStream (child)); 378 } 379 } 380 | Popular Tags |