You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by di...@apache.org on 2004/10/25 16:42:09 UTC

cvs commit: ws-axis/java/src/org/apache/axis/transport/http QSWSDLHandler.java

dims        2004/10/25 07:42:09

  Modified:    java/src/org/apache/axis/transport/http QSWSDLHandler.java
  Log:
  Fix for AXIS-1570 - Should provide automatic URL update in the WSDL when using <wsdlFile>
  from Ian P. Springer (ian.springer@hp.com)
  
  Revision  Changes    Path
  1.9       +103 -60   ws-axis/java/src/org/apache/axis/transport/http/QSWSDLHandler.java
  
  Index: QSWSDLHandler.java
  ===================================================================
  RCS file: /home/cvs/ws-axis/java/src/org/apache/axis/transport/http/QSWSDLHandler.java,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- QSWSDLHandler.java	18 Aug 2004 13:16:39 -0000	1.8
  +++ QSWSDLHandler.java	25 Oct 2004 14:42:09 -0000	1.9
  @@ -23,125 +23,168 @@
   import org.apache.axis.utils.Messages;
   import org.apache.axis.utils.XMLUtils;
   import org.w3c.dom.Document;
  +import org.w3c.dom.Node;
  +import org.w3c.dom.NodeList;
   
  -import javax.servlet.http.HttpServletRequest;
   import javax.servlet.http.HttpServletResponse;
   import java.io.PrintWriter;
   import java.net.HttpURLConnection;
   
   /**
    * The QSWSDLHandler class is a handler which provides an AXIS service's WSDL
  - * document when the query string "wsdl" is encountered in an AXIS servlet
  - * invocation.
  + * 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
    */
  -
   public class QSWSDLHandler extends AbstractQueryStringHandler {
  -
       /**
  -     * Performs the action associated with this particular query string
  -     * handler.
  +     * 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.
  +     *                   information for this query string handler.
  +     * @throws AxisFault if an error occurs
        */
  -
  -    public void invoke (MessageContext msgContext) throws AxisFault {
  +    public void invoke(MessageContext msgContext) throws AxisFault {
           // 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);
  -        HttpServletRequest request = (HttpServletRequest)
  -                msgContext.getProperty (HTTPConstants.MC_HTTP_SERVLETREQUEST);
           HttpServletResponse response = (HttpServletResponse)
  -                msgContext.getProperty (HTTPConstants.MC_HTTP_SERVLETRESPONSE);
  -
  +                msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE);
           try {
  -            engine.generateWSDL (msgContext);
  -
  -            Document doc = (Document) msgContext.getProperty ("WSDL");
  -
  -            if (doc != null) {
  -                response.setContentType ("text/xml; charset="+XMLUtils.getEncoding().toLowerCase());
  -                reportWSDL(doc, writer);
  -            }
  -
  -            else {
  +            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");
  +                    log.debug("processWsdlRequest: failed to create WSDL");
                   }
  -
  -                reportNoWSDL (response, writer, "noWSDL02", null);
  +                reportNoWSDL(response, writer, "noWSDL02", null);
               }
  -        }
  -
  -        catch (AxisFault axisFault) {
  +        } 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);
  +                processAxisFault(axisFault);
   
                   //then report under a 404 error
  -
  -                response.setStatus (HttpURLConnection.HTTP_NOT_FOUND);
  -
  -                reportNoWSDL (response, writer, "noWSDL01", axisFault);
  -            }
  -
  -            else {
  +                response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
  +                reportNoWSDL(response, writer, "noWSDL01", axisFault);
  +            } else {
                   //all other faults get thrown
  -
                   throw axisFault;
               }
           }
       }
   
       /**
  -     * report WSDL
  +     * Report WSDL.
  +     *
        * @param doc
        * @param writer
  -     */ 
  +     */
       public void reportWSDL(Document doc, PrintWriter writer) {
  -        XMLUtils.PrettyDocumentToWriter (doc, writer);
  +        XMLUtils.PrettyDocumentToWriter(doc, writer);
       }
   
       /**
  -     * report that we have no WSDL
  +     * 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
  +     * @param axisFault      optional fault string, for extra info at debug time only
        */
  -
  -    public void reportNoWSDL (HttpServletResponse res, PrintWriter writer,
  -                               String moreDetailCode, AxisFault axisFault) {
  -        res.setStatus (HttpURLConnection.HTTP_NOT_FOUND);
  -        res.setContentType ("text/html");
  -
  -        writer.println ("<h2>" + Messages.getMessage ("error00") + "</h2>");
  -        writer.println ("<p>" + Messages.getMessage ("noWSDL00") + "</p>");
  -
  +    public void reportNoWSDL(HttpServletResponse res, PrintWriter writer,
  +                             String moreDetailCode, AxisFault axisFault) {
  +        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)
  +            writer.println("<p>" + Messages.getMessage(moreDetailCode)
                       + "</p>");
           }
  -
           if (axisFault != null && isDevelopment()) {
               //dev systems only give fault dumps
  +            writeFault(writer, axisFault);
  +        }
  +    }
   
  -            writeFault (writer, axisFault);
  +    /**
  +     * Updates WSDL service location using URL from the request, so we are sure the returned WSDL 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 {@link org.apache.axis.description.ServiceDesc} for this service
  +     */
  +    protected void updateSoapAddressLocationURLs(Document wsdlDoc,
  +                                                 MessageContext msgContext)
  +            throws AxisFault {
  +        NodeList soapAddresses = wsdlDoc.getDocumentElement()
  +                .getElementsByTagNameNS(Constants.URI_WSDL11_SOAP, "address");
  +        if (soapAddresses == null || soapAddresses.getLength() == 0) {
  +            soapAddresses =
  +                    wsdlDoc.getDocumentElement().getElementsByTagNameNS(
  +                            Constants.URI_WSDL12_SOAP, "address");
  +        }
  +        if (soapAddresses != null) {
  +            String endpointURL = getEndpointURL(msgContext);
  +            log.debug("Setting soap:address location values in WSDL for service " +
  +                    msgContext.getTargetService() +
  +                    " to: " +
  +                    endpointURL);
  +            for (int i = 0; i < soapAddresses.getLength(); i++) {
  +                Node locationAttrib = soapAddresses.item(i).getAttributes()
  +                        .getNamedItem("location");
  +                locationAttrib.setNodeValue(endpointURL);
  +            }
           }
       }
   
  +    /**
  +     * 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
  +     */
  +    protected String getEndpointURL(MessageContext msgContext)
  +            throws AxisFault {
  +        // 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;
  +    }
   }