1 25 package org.objectweb.jonas.ws.axis; 26 27 import java.io.File ; 28 import java.io.IOException ; 29 import java.io.InputStream ; 30 import java.io.PrintWriter ; 31 import java.net.HttpURLConnection ; 32 import java.net.URL ; 33 import java.util.Iterator ; 34 import java.util.List ; 35 36 import javax.naming.InitialContext ; 37 import javax.naming.NamingException ; 38 import javax.servlet.http.HttpServletRequest ; 39 import javax.servlet.http.HttpServletResponse ; 40 import javax.wsdl.Definition; 41 import javax.wsdl.Port; 42 import javax.wsdl.Service; 43 import javax.wsdl.WSDLException; 44 import javax.wsdl.extensions.ExtensibilityElement; 45 import javax.wsdl.extensions.soap.SOAPAddress; 46 import javax.wsdl.factory.WSDLFactory; 47 import javax.wsdl.xml.WSDLReader; 48 import javax.wsdl.xml.WSDLWriter; 49 import javax.xml.namespace.QName ; 50 import javax.xml.parsers.DocumentBuilder ; 51 import javax.xml.parsers.DocumentBuilderFactory ; 52 import javax.xml.parsers.ParserConfigurationException ; 53 54 import org.w3c.dom.Attr ; 55 import org.w3c.dom.Document ; 56 import org.w3c.dom.Element ; 57 import org.w3c.dom.NodeList ; 58 import org.xml.sax.SAXException ; 59 60 import org.apache.axis.AxisFault; 61 import org.apache.axis.Constants; 62 import org.apache.axis.MessageContext; 63 import org.apache.axis.i18n.Messages; 64 import org.apache.axis.server.AxisServer; 65 import org.apache.axis.transport.http.AbstractQueryStringHandler; 66 import org.apache.axis.transport.http.HTTPConstants; 67 import org.apache.axis.utils.XMLUtils; 68 69 import org.objectweb.jonas_ws.deployment.api.PortComponentDesc; 70 import org.objectweb.jonas_ws.deployment.api.ServiceDesc; 71 72 import org.objectweb.jonas.ws.WSServiceException; 73 74 79 public class QSUpdateServiceWSDLHandler extends AbstractQueryStringHandler { 80 81 84 private static final String NS_URI_SOAP = "http://schemas.xmlsoap.org/wsdl/soap/"; 85 86 89 private static final QName QNAME_SOAP_ADDRESS = new QName (NS_URI_SOAP, "address"); 90 91 94 private static final String NS_URI_WSDL = "http://schemas.xmlsoap.org/wsdl/"; 95 96 99 private static final String NS_URI_XSD = "http://www.w3.org/2001/XMLSchema"; 100 101 104 private static final String PARAM_FILENAME = "filename"; 105 106 109 private static final String PARAM_CONTEXT = "context"; 110 111 114 private static final String PARAM_JWSDL = "JWSDL"; 115 116 119 private static final QName WSDL_DEFINITIONS_QNAME = new QName (NS_URI_WSDL, "definitions"); 120 121 124 private ServiceDesc sd = null; 125 126 132 public void invoke(MessageContext msgContext) throws AxisFault { 133 configureFromContext(msgContext); 136 137 AxisServer engine = (AxisServer) msgContext.getProperty(HTTPConstants.PLUGIN_ENGINE); 138 PrintWriter writer = (PrintWriter ) msgContext.getProperty(HTTPConstants.PLUGIN_WRITER); 139 HttpServletResponse response = (HttpServletResponse ) msgContext 140 .getProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE); 141 HttpServletRequest request = (HttpServletRequest ) msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST); 142 143 InitialContext ctx; 144 try { 145 ctx = new InitialContext (); 146 sd = (ServiceDesc) ctx.lookup("java:comp/jonas/" + engine.getName() + "/dd"); 147 } catch (NamingException e) { 148 throw new AxisFault("Servlet name not found : " + engine.getName(), e); 149 } 150 151 String wsdlFilename = request.getParameter(PARAM_FILENAME); 152 String context = request.getParameter(PARAM_CONTEXT); 153 try { 154 Document doc = null; 155 if (wsdlFilename == null) { 156 doc = getDefinitionAsDocument(sd.getWSDL().getDefinition()); 158 wsdlFilename = sd.getWSDL().getName(); 159 String [] pathElements = wsdlFilename.split("/"); 160 if (pathElements.length <= 2) { 161 throw new WSServiceException("invalid filename"); 162 } 163 164 StringBuffer buf = new StringBuffer (); 165 for (int i = 2; i < pathElements.length; i++) { 166 buf.append(pathElements[i]); 167 if (i != (pathElements.length - 1)) { 168 buf.append("/"); 170 } 171 } 172 wsdlFilename = buf.toString(); 175 context = "."; 176 msgContext.setProperty("WSDL", doc); 177 } else { 178 doc = (Document ) msgContext.getProperty("WSDL_" + wsdlFilename); 180 181 if (doc == null) { 182 doc = getDocument(wsdlFilename, context); 184 } 185 186 msgContext.setProperty("WSDL_" + wsdlFilename, doc); 187 } 188 189 if (doc != null) { 190 modifyImports(doc, request, new File (context, wsdlFilename).getParent()); 192 Document up2date = updateWSDLPortLocations(doc); 193 response.setContentType("text/xml; charset=" + XMLUtils.getEncoding().toLowerCase()); 194 reportWSDL(up2date, writer); 195 } else { 196 if (log.isDebugEnabled()) { 198 log.debug("processWsdlRequest: failed to create WSDL"); 199 } 200 reportNoWSDL(response, writer, "noWSDL02", null); 201 } 202 } catch (AxisFault axisFault) { 203 if (axisFault.getFaultCode().equals(Constants.QNAME_NO_SERVICE_FAULT_CODE)) { 205 processAxisFault(axisFault); 207 208 response.setStatus(HttpURLConnection.HTTP_NOT_FOUND); 210 reportNoWSDL(response, writer, "noWSDL01", axisFault); 211 } else { 212 throw axisFault; 214 } 215 } 216 } 217 218 223 private Document getDefinitionAsDocument(Definition definition) throws AxisFault { 224 225 try { 226 WSDLWriter writer = getWSDLWriter(); 227 return writer.getDocument(definition); 228 } catch (WSDLException e) { 229 throw new AxisFault(e.getMessage(), e); 230 } 231 232 } 233 234 240 private void modifyImports(Document doc, HttpServletRequest request, String context) { 241 244 Element de = doc.getDocumentElement(); 246 247 NodeList imports = de.getElementsByTagNameNS(NS_URI_WSDL, "import"); 248 249 for (int i = 0; i < imports.getLength(); i++) { 251 Element imp = (Element) imports.item(i); 252 Attr location = imp.getAttributeNode("location"); 253 if (!location.getValue().startsWith("http://")) { 254 String req = computeUpdatedURL(request, context, location); 256 257 log.debug("Replacing wsdl:location '" + location.getValue() + "' with '" + req.toString() + "'"); 258 location.setValue(req.toString()); 259 } 260 } 261 262 updateSchema(de, "include", request, context); 264 updateSchema(de, "import", request, context); 266 267 NodeList types = de.getElementsByTagNameNS(NS_URI_WSDL, "types"); 269 if (types.getLength() != 0) { 271 272 Element typesElement = (Element) types.item(0); 274 275 NodeList schemasList = typesElement.getElementsByTagNameNS(NS_URI_XSD, "schema"); 277 for (int i = 0; i < schemasList.getLength(); i++) { 278 Element schema = (Element) schemasList.item(i); 279 updateSchema(schema, "include", request, context); 280 updateSchema(schema, "import", request, context); 281 } 282 } 283 } 284 285 291 private String computeUpdatedURL(HttpServletRequest request, String context, Attr location) { 292 StringBuffer req = request.getRequestURL(); 293 req.append("?" + PARAM_JWSDL); 294 req.append("&" + PARAM_FILENAME + "=" + location.getValue()); 295 req.append("&" + PARAM_CONTEXT + "=" + context); 296 return req.toString(); 297 } 298 299 305 private void updateSchema(Element schema, String elementName, HttpServletRequest request, String context) { 306 307 NodeList elements = schema.getElementsByTagNameNS(NS_URI_XSD, elementName); 308 309 for (int i = 0; i < elements.getLength(); i++) { 311 Element e = (Element) elements.item(i); 312 Attr location = e.getAttributeNode("schemaLocation"); 313 if ((location != null) && (!location.getValue().startsWith("http://"))) { 314 String req = computeUpdatedURL(request, context, location); 316 317 log.debug("Replacing xsd:schemaLocation '" + location.getValue() + "' with '" + req.toString() + "'"); 318 location.setValue(req.toString()); 319 } 320 } 321 } 322 323 330 private Document getDocument(String wsdlFilename, String context) throws AxisFault { 331 332 336 ClassLoader cl = Thread.currentThread().getContextClassLoader(); 337 URL res = cl.getResource(context + "/" + wsdlFilename); 338 339 Document doc = null; 340 if (res != null) { 341 try { 342 doc = createDocument(res.openStream()); 343 } catch (IOException ioe) { 344 throw new AxisFault("Cannot open requested URL : " + res); 345 } 346 } else { 347 throw new AxisFault("Cannot find requested document : " + wsdlFilename); 348 } 349 350 return doc; 351 } 352 353 358 private Document createDocument(InputStream stream) throws AxisFault { 359 try { 360 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 361 factory.setNamespaceAware(true); 362 factory.setValidating(false); 363 DocumentBuilder builder = factory.newDocumentBuilder(); 364 return builder.parse(stream); 365 } catch (ParserConfigurationException pce) { 366 throw new AxisFault(pce.getMessage(), pce); 367 } catch (SAXException se) { 368 throw new AxisFault(se.getMessage(), se); 369 } catch (IOException ioe) { 370 throw new AxisFault(ioe.getMessage(), ioe); 371 } 372 } 373 374 380 private Document updateWSDLPortLocations(Document doc) throws AxisFault { 381 log.debug("Entering updateWSDL"); 382 383 QName docQname = new QName (doc.getDocumentElement().getNamespaceURI(), doc.getDocumentElement().getLocalName()); 384 385 if (WSDL_DEFINITIONS_QNAME.equals(docQname)) { 387 try { 388 WSDLReader reader = getWSDLReader(); 389 Definition def = reader.readWSDL(null, doc); 391 392 396 QName sQName = sd.getWSDL().getServiceQname(); 397 Service s = def.getService(sQName); 398 if (s != null) { 399 400 List portsComp = sd.getPortComponents(); 401 for (Iterator i = portsComp.iterator(); i.hasNext();) { 402 PortComponentDesc pcd = (PortComponentDesc) i.next(); 403 URL endpoint = pcd.getEndpointURL(); 404 QName portQName = pcd.getQName(); 405 406 Port port = s.getPort(portQName.getLocalPart()); 407 if (port != null) { 409 List ext = port.getExtensibilityElements(); 411 for (Iterator it = ext.iterator(); it.hasNext();) { 412 ExtensibilityElement element = (ExtensibilityElement) it.next(); 413 if (element.getElementType().equals(QNAME_SOAP_ADDRESS)) { 414 SOAPAddress sa = (SOAPAddress) element; 415 sa.setLocationURI(endpoint.toExternalForm()); 416 log.debug("Update port soap:location with " + endpoint); 417 } 418 } 419 } else { 420 log.warn("Cannot find wsdl:port '" + portQName.getLocalPart() + "' in wsdl:service " 421 + s.getQName()); 422 } 423 } 424 } 425 426 return WSDLFactory.newInstance().newWSDLWriter().getDocument(def); 427 } catch (WSDLException wsdle) { 428 throw new AxisFault("Cannot read WSDL Document", wsdle); 429 } 430 } else { 431 return doc; 434 } 435 436 } 437 438 442 private WSDLReader getWSDLReader() throws WSDLException { 443 WSDLFactory factory = WSDLFactory.newInstance(); 444 WSDLReader reader = factory.newWSDLReader(); 445 reader.setFeature("javax.wsdl.importDocuments", false); 446 return reader; 447 } 448 449 453 private WSDLWriter getWSDLWriter() throws WSDLException { 454 WSDLFactory factory = WSDLFactory.newInstance(); 455 return factory.newWSDLWriter(); 456 } 457 458 463 public void reportWSDL(Document doc, PrintWriter writer) { 464 XMLUtils.PrettyDocumentToWriter(doc, writer); 465 } 466 467 474 public void reportNoWSDL(HttpServletResponse res, PrintWriter writer, String moreDetailCode, AxisFault axisFault) { 475 res.setStatus(HttpURLConnection.HTTP_NOT_FOUND); 476 res.setContentType("text/html"); 477 478 writer.println("<h2>" + Messages.getMessage("error00") + "</h2>"); 479 writer.println("<p>" + Messages.getMessage("noWSDL00") + "</p>"); 480 481 if (moreDetailCode != null) { 482 writer.println("<p>" + Messages.getMessage(moreDetailCode) + "</p>"); 483 } 484 485 if (axisFault != null && isDevelopment()) { 486 writeFault(writer, axisFault); 488 } 489 } 490 491 } | Popular Tags |