KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > transport > http > QSWSDLHandler


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.axis.transport.http;
18
19 import org.apache.axis.AxisFault;
20 import org.apache.axis.Constants;
21 import org.apache.axis.MessageContext;
22 import org.apache.axis.ConfigurationException;
23 import org.apache.axis.description.ServiceDesc;
24 import org.apache.axis.server.AxisServer;
25 import org.apache.axis.utils.Messages;
26 import org.apache.axis.utils.XMLUtils;
27 import org.w3c.dom.Document JavaDoc;
28 import org.w3c.dom.Node JavaDoc;
29 import org.w3c.dom.NodeList JavaDoc;
30 import org.w3c.dom.Element JavaDoc;
31
32 import javax.servlet.http.HttpServletResponse JavaDoc;
33 import java.io.PrintWriter JavaDoc;
34 import java.net.HttpURLConnection JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.Set JavaDoc;
37 import java.util.HashSet JavaDoc;
38
39 /**
40  * The QSWSDLHandler class is a handler which provides an AXIS service's WSDL
41  * document when the query string "wsdl" (ignoring case) is encountered in an
42  * AXIS servlet invocation.
43  *
44  * @author Curtiss Howard (code mostly from AxisServlet class)
45  * @author Doug Davis (dug@us.ibm.com)
46  * @author Steve Loughran
47  * @author Ian P. Springer, Sal Campana
48  */

49 public class QSWSDLHandler extends AbstractQueryStringHandler {
50     /**
51      * Performs the action associated with this particular query string handler.
52      *
53      * @param msgContext a MessageContext object containing message context
54      * information for this query string handler.
55      * @throws AxisFault if an error occurs
56      */

57     public void invoke(MessageContext msgContext) throws AxisFault {
58         // Obtain objects relevant to the task at hand from the provided
59
// MessageContext's bag.
60
configureFromContext(msgContext);
61         AxisServer engine = (AxisServer) msgContext.getProperty
62                 (HTTPConstants.PLUGIN_ENGINE);
63         PrintWriter JavaDoc writer = (PrintWriter JavaDoc) msgContext.getProperty
64                 (HTTPConstants.PLUGIN_WRITER);
65         HttpServletResponse JavaDoc response = (HttpServletResponse JavaDoc)
66                 msgContext.getProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE);
67         try {
68             engine.generateWSDL(msgContext);
69             Document JavaDoc wsdlDoc = (Document JavaDoc) msgContext.getProperty("WSDL");
70             if (wsdlDoc != null) {
71                 try {
72                     updateSoapAddressLocationURLs(wsdlDoc, msgContext);
73                 } catch (RuntimeException JavaDoc re) {
74                     log.warn(
75                             "Failed to update soap:address location URL(s) in WSDL.",
76                             re);
77                 }
78                 response.setContentType(
79                         "text/xml; charset=" +
80                         XMLUtils.getEncoding().toLowerCase());
81                 reportWSDL(wsdlDoc, writer);
82             } else {
83                 if (log.isDebugEnabled()) {
84                     log.debug("processWsdlRequest: failed to create WSDL");
85                 }
86                 reportNoWSDL(response, writer, "noWSDL02", null);
87             }
88         } catch (AxisFault axisFault) {
89             //the no-service fault is mapped to a no-wsdl error
90
if (axisFault.getFaultCode().equals
91                     (Constants.QNAME_NO_SERVICE_FAULT_CODE)) {
92                 //which we log
93
processAxisFault(axisFault);
94
95                 //then report under a 404 error
96
response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
97                 reportNoWSDL(response, writer, "noWSDL01", axisFault);
98             } else {
99                 //all other faults get thrown
100
throw axisFault;
101             }
102         }
103     }
104
105     /**
106      * Report WSDL.
107      *
108      * @param doc
109      * @param writer
110      */

111     public void reportWSDL(Document JavaDoc doc, PrintWriter JavaDoc writer) {
112         XMLUtils.PrettyDocumentToWriter(doc, writer);
113     }
114
115     /**
116      * Report that we have no WSDL.
117      *
118      * @param res
119      * @param writer
120      * @param moreDetailCode optional name of a message to provide more detail
121      * @param axisFault optional fault string, for extra info at debug time only
122      */

123     public void reportNoWSDL(HttpServletResponse JavaDoc res, PrintWriter JavaDoc writer,
124                              String JavaDoc moreDetailCode, AxisFault axisFault) {
125         res.setStatus(HttpURLConnection.HTTP_NOT_FOUND);
126         res.setContentType("text/html");
127         writer.println("<h2>" + Messages.getMessage("error00") + "</h2>");
128         writer.println("<p>" + Messages.getMessage("noWSDL00") + "</p>");
129         if (moreDetailCode != null) {
130             writer.println("<p>" + Messages.getMessage(moreDetailCode)
131                     + "</p>");
132         }
133         if (axisFault != null && isDevelopment()) {
134             //only dev systems give fault dumps
135
writeFault(writer, axisFault);
136         }
137     }
138
139     /**
140      * Updates the soap:address locations for all ports in the WSDL using the URL from the request as
141      * the base portion for the updated locations, ensuring the WSDL returned to the client contains
142      * the correct location URL.
143      *
144      * @param wsdlDoc the WSDL as a DOM document
145      * @param msgContext the current Axis JAX-RPC message context
146      * @throws AxisFault if we fail to obtain the list of deployed service names from the server config
147      */

148     protected void updateSoapAddressLocationURLs(Document JavaDoc wsdlDoc,
149                                                  MessageContext msgContext)
150             throws AxisFault {
151         Set JavaDoc deployedServiceNames;
152         try {
153             deployedServiceNames = getDeployedServiceNames(msgContext);
154         }
155         catch (ConfigurationException ce) {
156             throw new AxisFault("Failed to determine deployed service names.", ce);
157         }
158         NodeList JavaDoc wsdlPorts = wsdlDoc.getDocumentElement().getElementsByTagNameNS(Constants.NS_URI_WSDL11, "port");
159         if (wsdlPorts != null) {
160             String JavaDoc endpointURL = getEndpointURL(msgContext);
161             String JavaDoc baseEndpointURL = endpointURL.substring(0, endpointURL.lastIndexOf("/") + 1);
162             for (int i = 0; i < wsdlPorts.getLength(); i++) {
163                 Element JavaDoc portElem = (Element JavaDoc) wsdlPorts.item(i);
164                 Node JavaDoc portNameAttrib = portElem.getAttributes().getNamedItem("name");
165                 if (portNameAttrib == null) {
166                     continue;
167                 }
168                 String JavaDoc portName = portNameAttrib.getNodeValue();
169                 NodeList JavaDoc soapAddresses = portElem.getElementsByTagNameNS(Constants.URI_WSDL11_SOAP, "address");
170                 if (soapAddresses == null || soapAddresses.getLength() == 0) {
171                     soapAddresses = portElem.getElementsByTagNameNS(Constants.URI_WSDL12_SOAP, "address");
172                 }
173                 if (soapAddresses != null) {
174                     for (int j = 0; j < soapAddresses.getLength(); j++) {
175                         Element JavaDoc addressElem = (Element JavaDoc) soapAddresses.item(j);
176                         Node JavaDoc addressLocationAttrib = addressElem.getAttributes().getNamedItem("location");
177                         if ( addressLocationAttrib == null )
178                         {
179                             continue;
180                         }
181                         String JavaDoc addressLocation = addressLocationAttrib.getNodeValue();
182                         String JavaDoc addressServiceName = addressLocation.substring(addressLocation.lastIndexOf("/") + 1);
183                         String JavaDoc newServiceName = getNewServiceName(deployedServiceNames, addressServiceName, portName);
184                         if (newServiceName != null) {
185                             String JavaDoc newAddressLocation = baseEndpointURL + newServiceName;
186                             addressLocationAttrib.setNodeValue(newAddressLocation);
187                             log.debug("Setting soap:address location values in WSDL for port " +
188                                     portName +
189                                     " to: " +
190                                     newAddressLocation);
191                         }
192                         else
193                         {
194                             log.debug("For WSDL port: " + portName + ", unable to match port name or the last component of " +
195                                     "the SOAP address url with a " +
196                                     "service name deployed in server-config.wsdd. Leaving SOAP address: " +
197                                     addressLocation + " unmodified.");
198                         }
199                     }
200                 }
201             }
202         }
203     }
204
205     private String JavaDoc getNewServiceName(Set JavaDoc deployedServiceNames, String JavaDoc currentServiceEndpointName, String JavaDoc portName) {
206         String JavaDoc endpointName = null;
207         if (deployedServiceNames.contains(currentServiceEndpointName)) {
208             endpointName = currentServiceEndpointName;
209         }
210         else if (deployedServiceNames.contains(portName)) {
211             endpointName = portName;
212         }
213         return endpointName;
214     }
215
216     private Set JavaDoc getDeployedServiceNames(MessageContext msgContext) throws ConfigurationException {
217         Set JavaDoc serviceNames = new HashSet JavaDoc();
218         Iterator JavaDoc deployedServicesIter = msgContext.getAxisEngine().getConfig().getDeployedServices();
219         while (deployedServicesIter.hasNext()) {
220             ServiceDesc serviceDesc = (ServiceDesc) deployedServicesIter.next();
221             serviceNames.add(serviceDesc.getName());
222         }
223         return serviceNames;
224     }
225
226     /**
227      * Returns the endpoint URL that should be used in the returned WSDL.
228      *
229      * @param msgContext the current Axis JAX-RPC message context
230      * @return the endpoint URL that should be used in the returned WSDL
231      * @throws AxisFault if we fail to obtain the {@link org.apache.axis.description.ServiceDesc} for this service
232      */

233     protected String JavaDoc getEndpointURL(MessageContext msgContext)
234             throws AxisFault {
235         // First see if a location URL is explicitly set in the MC.
236
String JavaDoc locationUrl = msgContext.getStrProp(
237                 MessageContext.WSDLGEN_SERV_LOC_URL);
238         if (locationUrl == null) {
239             // If nothing, try what's explicitly set in the ServiceDesc.
240
locationUrl =
241                     msgContext.getService().getInitializedServiceDesc(
242                             msgContext)
243                     .getEndpointURL();
244         }
245         if (locationUrl == null) {
246             // If nothing, use the actual transport URL.
247
locationUrl = msgContext.getStrProp(MessageContext.TRANS_URL);
248         }
249         return locationUrl;
250     }
251 }
252
Popular Tags