FileDocCategorySizeDatePackage
QSWSDLHandler.javaAPI DocApache Axis 1.411040Sat Apr 22 18:57:28 BST 2006org.apache.axis.transport.http

QSWSDLHandler

public class QSWSDLHandler extends AbstractQueryStringHandler
The QSWSDLHandler class is a handler which provides an AXIS service's WSDL document when the query string "wsdl" (ignoring case) is encountered in an AXIS servlet invocation.
author
Curtiss Howard (code mostly from AxisServlet class)
author
Doug Davis (dug@us.ibm.com)
author
Steve Loughran
author
Ian P. Springer, Sal Campana

Fields Summary
Constructors Summary
Methods Summary
private java.util.SetgetDeployedServiceNames(org.apache.axis.MessageContext msgContext)

        Set serviceNames = new HashSet();
        Iterator deployedServicesIter = msgContext.getAxisEngine().getConfig().getDeployedServices();
        while (deployedServicesIter.hasNext()) {
            ServiceDesc serviceDesc = (ServiceDesc) deployedServicesIter.next();
            serviceNames.add(serviceDesc.getName());
        }
        return serviceNames;
    
protected java.lang.StringgetEndpointURL(org.apache.axis.MessageContext msgContext)
Returns the endpoint URL that should be used in the returned WSDL.

param
msgContext the current Axis JAX-RPC message context
return
the endpoint URL that should be used in the returned WSDL
throws
AxisFault if we fail to obtain the {@link org.apache.axis.description.ServiceDesc} for this service

        // First see if a location URL is explicitly set in the MC.
        String locationUrl = msgContext.getStrProp(
                MessageContext.WSDLGEN_SERV_LOC_URL);
        if (locationUrl == null) {
            // If nothing, try what's explicitly set in the ServiceDesc.
            locationUrl =
                    msgContext.getService().getInitializedServiceDesc(
                            msgContext)
                    .getEndpointURL();
        }
        if (locationUrl == null) {
            // If nothing, use the actual transport URL.
            locationUrl = msgContext.getStrProp(MessageContext.TRANS_URL);
        }
        return locationUrl;
    
private java.lang.StringgetNewServiceName(java.util.Set deployedServiceNames, java.lang.String currentServiceEndpointName, java.lang.String portName)

        String endpointName = null;
        if (deployedServiceNames.contains(currentServiceEndpointName)) {
            endpointName = currentServiceEndpointName;
        }
        else if (deployedServiceNames.contains(portName)) {
            endpointName = portName;
        }
        return endpointName;
    
public voidinvoke(org.apache.axis.MessageContext msgContext)
Performs the action associated with this particular query string handler.

param
msgContext a MessageContext object containing message context information for this query string handler.
throws
AxisFault if an error occurs

        // Obtain objects relevant to the task at hand from the provided
        // MessageContext's bag.
        configureFromContext(msgContext);
        AxisServer engine = (AxisServer) msgContext.getProperty
                (HTTPConstants.PLUGIN_ENGINE);
        PrintWriter writer = (PrintWriter) msgContext.getProperty
                (HTTPConstants.PLUGIN_WRITER);
        HttpServletResponse response = (HttpServletResponse)
                msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE);
        try {
            engine.generateWSDL(msgContext);
            Document wsdlDoc = (Document) msgContext.getProperty("WSDL");
            if (wsdlDoc != null) {
                try {
                    updateSoapAddressLocationURLs(wsdlDoc, msgContext);
                } catch (RuntimeException re) {
                    log.warn(
                            "Failed to update soap:address location URL(s) in WSDL.",
                            re);
                }
                response.setContentType(
                        "text/xml; charset=" +
                        XMLUtils.getEncoding().toLowerCase());
                reportWSDL(wsdlDoc, writer);
            } else {
                if (log.isDebugEnabled()) {
                    log.debug("processWsdlRequest: failed to create WSDL");
                }
                reportNoWSDL(response, writer, "noWSDL02", null);
            }
        } catch (AxisFault axisFault) {
            //the no-service fault is mapped to a no-wsdl error
            if (axisFault.getFaultCode().equals
                    (Constants.QNAME_NO_SERVICE_FAULT_CODE)) {
                //which we log
                processAxisFault(axisFault);

                //then report under a 404 error
                response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
                reportNoWSDL(response, writer, "noWSDL01", axisFault);
            } else {
                //all other faults get thrown
                throw axisFault;
            }
        }
    
public voidreportNoWSDL(javax.servlet.http.HttpServletResponse res, java.io.PrintWriter writer, java.lang.String moreDetailCode, org.apache.axis.AxisFault axisFault)
Report that we have no WSDL.

param
res
param
writer
param
moreDetailCode optional name of a message to provide more detail
param
axisFault optional fault string, for extra info at debug time only

        res.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
        res.setContentType("text/html");
        writer.println("<h2>" + Messages.getMessage("error00") + "</h2>");
        writer.println("<p>" + Messages.getMessage("noWSDL00") + "</p>");
        if (moreDetailCode != null) {
            writer.println("<p>" + Messages.getMessage(moreDetailCode)
                    + "</p>");
        }
        if (axisFault != null && isDevelopment()) {
            //only dev systems give fault dumps
            writeFault(writer, axisFault);
        }
    
public voidreportWSDL(org.w3c.dom.Document doc, java.io.PrintWriter writer)
Report WSDL.

param
doc
param
writer

        XMLUtils.PrettyDocumentToWriter(doc, writer);
    
protected voidupdateSoapAddressLocationURLs(org.w3c.dom.Document wsdlDoc, org.apache.axis.MessageContext msgContext)
Updates the soap:address locations for all ports in the WSDL using the URL from the request as the base portion for the updated locations, ensuring the WSDL returned to the client contains the correct location URL.

param
wsdlDoc the WSDL as a DOM document
param
msgContext the current Axis JAX-RPC message context
throws
AxisFault if we fail to obtain the list of deployed service names from the server config

        Set deployedServiceNames;
        try {
            deployedServiceNames = getDeployedServiceNames(msgContext);
        }
        catch (ConfigurationException ce) {
            throw new AxisFault("Failed to determine deployed service names.", ce);
        }
        NodeList wsdlPorts = wsdlDoc.getDocumentElement().getElementsByTagNameNS(Constants.NS_URI_WSDL11, "port");
        if (wsdlPorts != null) {
            String endpointURL = getEndpointURL(msgContext);
            String baseEndpointURL = endpointURL.substring(0, endpointURL.lastIndexOf("/") + 1);
            for (int i = 0; i < wsdlPorts.getLength(); i++) {
                Element portElem = (Element) wsdlPorts.item(i);
                Node portNameAttrib = portElem.getAttributes().getNamedItem("name");
                if (portNameAttrib == null) {
                    continue;
                }
                String portName = portNameAttrib.getNodeValue();
                NodeList soapAddresses = portElem.getElementsByTagNameNS(Constants.URI_WSDL11_SOAP, "address");
                if (soapAddresses == null || soapAddresses.getLength() == 0) {
                    soapAddresses = portElem.getElementsByTagNameNS(Constants.URI_WSDL12_SOAP, "address");
                }
                if (soapAddresses != null) {
                    for (int j = 0; j < soapAddresses.getLength(); j++) {
                        Element addressElem = (Element) soapAddresses.item(j);
                        Node addressLocationAttrib = addressElem.getAttributes().getNamedItem("location");
                        if ( addressLocationAttrib == null )
                        {
                            continue;
                        }
                        String addressLocation = addressLocationAttrib.getNodeValue();
                        String addressServiceName = addressLocation.substring(addressLocation.lastIndexOf("/") + 1);
                        String newServiceName = getNewServiceName(deployedServiceNames, addressServiceName, portName);
                        if (newServiceName != null) {
                            String newAddressLocation = baseEndpointURL + newServiceName;
                            addressLocationAttrib.setNodeValue(newAddressLocation);
                            log.debug("Setting soap:address location values in WSDL for port " +
                                    portName +
                                    " to: " +
                                    newAddressLocation);
                        }
                        else
                        {
                            log.debug("For WSDL port: " + portName + ", unable to match port name or the last component of " +
                                    "the SOAP address url with a " +
                                    "service name deployed in server-config.wsdd.  Leaving SOAP address: " +
                                    addressLocation + " unmodified.");
                        }
                    }
                }
            }
        }