KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > jmeter > protocol > http > util > WSDLHelper


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

18
19 package org.apache.jmeter.protocol.http.util;
20
21 import java.io.IOException JavaDoc;
22 import java.net.HttpURLConnection JavaDoc;
23 import java.net.MalformedURLException JavaDoc;
24 import java.net.URL JavaDoc;
25 import java.util.ArrayList JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Set JavaDoc;
28
29 import javax.xml.parsers.DocumentBuilder JavaDoc;
30 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
31 import javax.xml.parsers.ParserConfigurationException JavaDoc;
32
33 import org.w3c.dom.Document JavaDoc;
34 import org.w3c.dom.Element JavaDoc;
35 import org.w3c.dom.Node JavaDoc;
36 import org.w3c.dom.NodeList JavaDoc;
37 import org.xml.sax.SAXException JavaDoc;
38
39 /**
40  * For now I use DOM for WSDLHelper, but it would be more efficient to use JAXB
41  * to generate an object model for WSDL and use it to perform serialization
42  * and deserialization. It also makes it easier to traverse the WSDL to get
43  * necessary information.
44  * <p>
45  * Created on: Jun 3, 2003<br>
46  *
47  * @author Peter Lin
48  * @version $Revision: 1.5 $
49  */

50 public class WSDLHelper
51 {
52     /**
53      * --------------------------------------------
54      * The members used by the class to do its work
55      * --------------------------------------------
56      */

57
58     protected URL JavaDoc WSDLURL = null;
59     protected HttpURLConnection JavaDoc CONN = null;
60     protected Document JavaDoc WSDLDOC = null;
61     protected String JavaDoc SOAPBINDING = null;
62     public String JavaDoc BINDNAME = null;
63     protected Object JavaDoc[] SOAPOPS = null;
64     protected HashMap JavaDoc ACTIONS = new HashMap JavaDoc();
65
66     /**
67      * Default constructor takes a string URL
68      */

69     public WSDLHelper(String JavaDoc url) throws MalformedURLException JavaDoc
70     {
71         try
72         {
73             WSDLURL = new URL JavaDoc(url);
74         }
75         catch (MalformedURLException JavaDoc exception)
76         {
77             throw exception;
78         }
79     }
80
81     /**
82      * Returns the URL
83      * @return the URL
84      */

85     public URL JavaDoc getURL()
86     {
87         return this.WSDLURL;
88     }
89
90     /**
91      * Returns the binding point for the webservice. Right now it naively
92      * assumes there's only one binding point with numerous soap operations.
93      * @return String
94      */

95     public String JavaDoc getBinding()
96     {
97         try
98         {
99             NodeList JavaDoc services = this.WSDLDOC.getElementsByTagName("service");
100             // the document should only have one service node
101
// if it doesn't it may not work!
102
Element JavaDoc node = (Element JavaDoc) services.item(0);
103             NodeList JavaDoc ports = node.getElementsByTagName("port");
104             for (int idx = 0; idx < ports.getLength(); idx++)
105             {
106                 Element JavaDoc pnode = (Element JavaDoc) ports.item(idx);
107                 String JavaDoc portname = pnode.getAttribute("name");
108                 // got the port name. now check it against the
109
// binding name.
110
if (portname.equals(this.BINDNAME))
111                 {
112                     NodeList JavaDoc servlist =
113                         pnode.getElementsByTagName("soap:address");
114                     Element JavaDoc addr = (Element JavaDoc) servlist.item(0);
115                     this.SOAPBINDING = addr.getAttribute("location");
116                     return this.SOAPBINDING;
117                 }
118             }
119             return null;
120         }
121         catch (Exception JavaDoc exception)
122         {
123             return null;
124         }
125     }
126
127     /**
128      * Method is used internally to connect to the URL. It's protected;
129      * therefore external classes should use parse to get the resource
130      * at the given location.
131      * @throws IOException
132      */

133     protected void connect() throws IOException JavaDoc
134     {
135         try
136         {
137             CONN = (HttpURLConnection JavaDoc) WSDLURL.openConnection();
138         }
139         catch (IOException JavaDoc exception)
140         {
141             throw exception;
142         }
143     }
144
145     /**
146      * We try to close the connection to make sure it doesn't hang around.
147      */

148     protected void close()
149     {
150         try
151         {
152             CONN.getInputStream().close();
153         }
154         catch (Exception JavaDoc exception)
155         {
156             // do nothing
157
}
158     }
159
160     /**
161      * Method is used internally to parse the InputStream and build the
162      * document using javax.xml.parser API.
163      */

164     protected void buildDocument()
165         throws ParserConfigurationException JavaDoc, IOException JavaDoc, SAXException JavaDoc
166     {
167         try
168         {
169             DocumentBuilderFactory JavaDoc dbfactory =
170                 DocumentBuilderFactory.newInstance();
171             DocumentBuilder JavaDoc docbuild = dbfactory.newDocumentBuilder();
172             WSDLDOC = docbuild.parse(CONN.getInputStream());
173         }
174         catch (ParserConfigurationException JavaDoc exception)
175         {
176             throw exception;
177         }
178         catch (IOException JavaDoc exception)
179         {
180             throw exception;
181         }
182         catch (SAXException JavaDoc exception)
183         {
184             throw exception;
185         }
186     }
187
188     /**
189      * Call this method to retrieve the WSDL. This method must be called,
190      * otherwise a connection to the URL won't be made and the stream won't be
191      * parsed.
192      */

193     public void parse() throws WSDLException
194     {
195         try
196         {
197             this.connect();
198             this.buildDocument();
199             SOAPOPS = this.getOperations();
200             this.close();
201         }
202         catch (IOException JavaDoc exception)
203         {
204             throw (new WSDLException(exception));
205         }
206         catch (Exception JavaDoc exception)
207         {
208             throw (new WSDLException(exception));
209         }
210     }
211
212     /**
213      * Get a list of the web methods as a string array.
214      */

215     public String JavaDoc[] getWebMethods()
216     {
217         for (int idx = 0; idx < SOAPOPS.length; idx++)
218         {
219             // get the node
220
Node JavaDoc act = (Node JavaDoc) SOAPOPS[idx];
221             // get the soap:operation
222
NodeList JavaDoc opers =
223                 ((Element JavaDoc) act).getElementsByTagName("soap:operation");
224             // there should only be one soap:operation node per operation
225
Element JavaDoc op = (Element JavaDoc) opers.item(0);
226             String JavaDoc value = op.getAttribute("soapAction");
227             String JavaDoc key = ((Element JavaDoc) act).getAttribute("name");
228             this.ACTIONS.put(key, value);
229         }
230         Set JavaDoc keys = this.ACTIONS.keySet();
231         String JavaDoc[] stringmeth = new String JavaDoc[keys.size()];
232         Object JavaDoc[] stringKeys = keys.toArray();
233         System.arraycopy(stringKeys, 0, stringmeth, 0, keys.size());
234         return stringmeth;
235     }
236
237     /**
238      * Return the soap action matching the operation name.
239      */

240     public String JavaDoc getSoapAction(String JavaDoc key)
241     {
242         return (String JavaDoc) this.ACTIONS.get(key);
243     }
244
245     /**
246      * Get the wsdl document.
247      */

248     public Document JavaDoc getWSDLDocument()
249     {
250         return WSDLDOC;
251     }
252
253     /**
254      * Method will look at the binding nodes and see if the first child is a
255      * soap:binding. If it is, it adds it to an array.
256      * @return Node[]
257      */

258     public Object JavaDoc[] getSOAPBindings()
259     {
260         ArrayList JavaDoc list = new ArrayList JavaDoc();
261         NodeList JavaDoc bindings = WSDLDOC.getElementsByTagName("binding");
262         for (int idx = 0; idx < bindings.getLength(); idx++)
263         {
264             Element JavaDoc nd = (Element JavaDoc) bindings.item(idx);
265             NodeList JavaDoc slist = nd.getElementsByTagName("soap:binding");
266             if (slist.getLength() > 0)
267             {
268                 //NOTUSED Element soapbind = (Element) slist.item(0);
269
this.BINDNAME = nd.getAttribute("name");
270                 list.add(nd);
271             }
272         }
273         if (list.size() > 0)
274         {
275             return list.toArray();
276         }
277         else
278         {
279             return new Object JavaDoc[0];
280         }
281     }
282
283     /**
284      * Look at the bindings with soap operations and get the soap operations.
285      * Since WSDL may describe multiple bindings and each binding may have
286      * multiple soap operations, we iterate through the binding nodes with a
287      * first child that is a soap binding. If a WSDL doesn't use the same
288      * formatting convention, it is possible we may not get a list of all the
289      * soap operations. If that is the case, getSOAPBindings() will need to be
290      * changed. I should double check the WSDL spec to see what the official
291      * requirement is. Another option is to get all operation nodes and check
292      * to see if the first child is a soap:operation. The benefit of not
293      * getting all operation nodes is WSDL could contain duplicate operations
294      * that are not SOAP methods. If there are a large number of methods and
295      * half of them are HTTP operations, getting all operations could slow
296      * things down.
297      * @return Node[]
298      */

299     public Object JavaDoc[] getOperations()
300     {
301         Object JavaDoc[] res = this.getSOAPBindings();
302         ArrayList JavaDoc ops = new ArrayList JavaDoc();
303         // first we iterate through the bindings
304
for (int idx = 0; idx < res.length; idx++)
305         {
306             Element JavaDoc one = (Element JavaDoc) res[idx];
307             NodeList JavaDoc opnodes = one.getElementsByTagName("operation");
308             // now we iterate through the operations
309
for (int idz = 0; idz < opnodes.getLength(); idz++)
310             {
311                 // if the first child is soap:operation
312
// we add it to the array
313
Element JavaDoc child = (Element JavaDoc) opnodes.item(idz);
314                 NodeList JavaDoc soapnode =
315                     child.getElementsByTagName("soap:operation");
316                 if (soapnode.getLength() > 0)
317                 {
318                     ops.add(child);
319                 }
320             }
321         }
322         return ops.toArray();
323     }
324
325     /**
326      * Simple test for the class uses bidbuy.wsdl from Apache's soap driver
327      * examples.
328      * @param args
329      */

330     public static void main(String JavaDoc[] args)
331     {
332         try
333         {
334             WSDLHelper help =
335                 new WSDLHelper("http://localhost/testWS/Service1.asmx?WSDL");
336             long start = System.currentTimeMillis();
337             help.parse();
338             String JavaDoc[] methods = help.getWebMethods();
339             System.out.println("el: " + (System.currentTimeMillis() - start));
340             for (int idx = 0; idx < methods.length; idx++)
341             {
342                 System.out.println("method name: " + methods[idx]);
343             }
344             System.out.println("service url: " + help.getBinding());
345         }
346         catch (Exception JavaDoc exception)
347         {
348             System.out.println("main method catch:");
349             exception.printStackTrace();
350         }
351     }
352 }
353
Popular Tags