Source code: org/apache/axis/wsdl/gen/Parser.java
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 package org.apache.axis.wsdl.gen;
17
18 import org.apache.axis.utils.Messages;
19 import org.apache.axis.wsdl.symbolTable.BindingEntry;
20 import org.apache.axis.wsdl.symbolTable.CollectionElement;
21 import org.apache.axis.wsdl.symbolTable.MessageEntry;
22 import org.apache.axis.wsdl.symbolTable.PortTypeEntry;
23 import org.apache.axis.wsdl.symbolTable.ServiceEntry;
24 import org.apache.axis.wsdl.symbolTable.SymTabEntry;
25 import org.apache.axis.wsdl.symbolTable.SymbolTable;
26 import org.apache.axis.wsdl.toJava.Utils;
27 import org.apache.axis.wsdl.symbolTable.Type;
28 import org.apache.axis.wsdl.symbolTable.TypeEntry;
29 import org.w3c.dom.Document;
30 import org.xml.sax.SAXException;
31
32 import javax.wsdl.Binding;
33 import javax.wsdl.Definition;
34 import javax.wsdl.WSDLException;
35 import javax.xml.parsers.ParserConfigurationException;
36 import java.io.IOException;
37 import java.util.Collection;
38 import java.util.Iterator;
39 import java.util.Map;
40 import java.util.Vector;
41
42 /**
43 * This is a class with no documentation.
44 */
45 public class Parser {
46
47 /** Field debug */
48 protected boolean debug = false;
49
50 /** Field quiet */
51 protected boolean quiet = false;
52
53 /** Field imports */
54 protected boolean imports = true;
55
56 /** Field verbose */
57 protected boolean verbose = false;
58
59 /** Field nowrap */
60 protected boolean nowrap = false;
61
62 // Username and password for Authentication
63
64 /** Field username */
65 protected String username = null;
66
67 /** Field password */
68 protected String password = null;
69
70 /** If this is false, we'll prefer "String[]" to "ArrayOfString" for literal wrapped arrays */
71 protected boolean wrapArrays = false;
72
73 // Timeout, in milliseconds, to let the Emitter do its work
74
75 /** Field timeoutms */
76 private long timeoutms = 45000; // 45 sec default
77
78 /** Field genFactory */
79 private GeneratorFactory genFactory = null;
80
81 /** Field symbolTable */
82 private SymbolTable symbolTable = null;
83
84 /**
85 * Method isDebug
86 *
87 * @return
88 */
89 public boolean isDebug() {
90 return debug;
91 } // isDebug
92
93 /**
94 * Method setDebug
95 *
96 * @param debug
97 */
98 public void setDebug(boolean debug) {
99 this.debug = debug;
100 } // setDebug
101
102 /**
103 * Method isQuiet
104 *
105 * @return
106 */
107 public boolean isQuiet() {
108 return quiet;
109 }
110
111 /**
112 * Method setQuiet
113 *
114 * @param quiet
115 */
116 public void setQuiet(boolean quiet) {
117 this.quiet = quiet;
118 }
119
120 /**
121 * Method isImports
122 *
123 * @return
124 */
125 public boolean isImports() {
126 return imports;
127 } // isImports
128
129 /**
130 * Method setImports
131 *
132 * @param imports
133 */
134 public void setImports(boolean imports) {
135 this.imports = imports;
136 } // setImports
137
138 /**
139 * Method isVerbose
140 *
141 * @return
142 */
143 public boolean isVerbose() {
144 return verbose;
145 } // isVerbose
146
147 /**
148 * Method setVerbose
149 *
150 * @param verbose
151 */
152 public void setVerbose(boolean verbose) {
153 this.verbose = verbose;
154 } // setVerbose
155
156 /**
157 * Method isNowrap
158 *
159 * @return
160 */
161 public boolean isNowrap() {
162 return nowrap;
163 }
164
165 /**
166 * Method setNowrap
167 *
168 * @param nowrap
169 */
170 public void setNowrap(boolean nowrap) {
171 this.nowrap = nowrap;
172 }
173
174 /**
175 * Return the current timeout setting
176 *
177 * @return
178 */
179 public long getTimeout() {
180 return timeoutms;
181 }
182
183 /**
184 * Set the timeout, in milliseconds
185 *
186 * @param timeout
187 */
188 public void setTimeout(long timeout) {
189 this.timeoutms = timeout;
190 }
191
192 /**
193 * Method getUsername
194 *
195 * @return
196 */
197 public String getUsername() {
198 return username;
199 } // getUsername
200
201 /**
202 * Method setUsername
203 *
204 * @param username
205 */
206 public void setUsername(String username) {
207 this.username = username;
208 } // setUsername
209
210 /**
211 * Method getPassword
212 *
213 * @return
214 */
215 public String getPassword() {
216 return password;
217 } // getPassword
218
219 /**
220 * Method setPassword
221 *
222 * @param password
223 */
224 public void setPassword(String password) {
225 this.password = password;
226 } // setPassword
227
228 /**
229 * Method getFactory
230 *
231 * @return
232 */
233 public GeneratorFactory getFactory() {
234 return genFactory;
235 } // getFactory
236
237 /**
238 * Method setFactory
239 *
240 * @param factory
241 */
242 public void setFactory(GeneratorFactory factory) {
243 this.genFactory = factory;
244 } // setFactory
245
246 /**
247 * Get the symbol table. The symbol table is null until
248 * run is called.
249 *
250 * @return
251 */
252 public SymbolTable getSymbolTable() {
253 return symbolTable;
254 } // getSymbolTable
255
256 /**
257 * Return the current definition. The current definition is
258 * null until run is called.
259 *
260 * @return
261 */
262 public Definition getCurrentDefinition() {
263
264 return (symbolTable == null)
265 ? null
266 : symbolTable.getDefinition();
267 } // getCurrentDefinition
268
269 /**
270 * Get the current WSDL URI. The WSDL URI is null until
271 * run is called.
272 *
273 * @return
274 */
275 public String getWSDLURI() {
276
277 return (symbolTable == null)
278 ? null
279 : symbolTable.getWSDLURI();
280 } // getWSDLURI
281
282 /**
283 * Parse a WSDL at a given URL.
284 * <p/>
285 * This method will time out after the number of milliseconds specified
286 * by our timeoutms member.
287 *
288 * @param wsdlURI
289 * @throws Exception
290 */
291 public void run(String wsdlURI) throws Exception {
292
293 if (getFactory() == null) {
294 setFactory(new NoopFactory());
295 }
296
297 symbolTable = new SymbolTable(genFactory.getBaseTypeMapping(), imports,
298 verbose, nowrap);
299 symbolTable.setQuiet(quiet);
300 symbolTable.setWrapArrays(wrapArrays);
301
302 // We run the actual Emitter in a thread that we can kill
303 WSDLRunnable runnable = new WSDLRunnable(symbolTable, wsdlURI);
304 Thread wsdlThread = new Thread(runnable);
305
306 wsdlThread.start();
307
308 try {
309 if (timeoutms > 0) {
310 wsdlThread.join(timeoutms);
311 } else {
312 wsdlThread.join();
313 }
314 } catch (InterruptedException e) {
315 }
316
317 if (wsdlThread.isAlive()) {
318 wsdlThread.interrupt();
319
320 throw new IOException(Messages.getMessage("timedOut"));
321 }
322
323 if (runnable.getFailure() != null) {
324 throw runnable.getFailure();
325 }
326 } // run
327
328 /**
329 * Class WSDLRunnable
330 *
331 * @version %I%, %G%
332 */
333 private class WSDLRunnable implements Runnable {
334
335 /** Field symbolTable */
336 private SymbolTable symbolTable;
337
338 /** Field wsdlURI */
339 private String wsdlURI;
340
341 /** Field failure */
342 private Exception failure = null;
343
344 /**
345 * Constructor WSDLRunnable
346 *
347 * @param symbolTable
348 * @param wsdlURI
349 */
350 public WSDLRunnable(SymbolTable symbolTable, String wsdlURI) {
351 this.symbolTable = symbolTable;
352 this.wsdlURI = wsdlURI;
353 } // ctor
354
355 /**
356 * Method run
357 */
358 public void run() {
359
360 try {
361 symbolTable.populate(wsdlURI, username, password);
362 generate(symbolTable);
363 } catch (Exception e) {
364 failure = e;
365 }
366 } // run
367
368 /**
369 * Method getFailure
370 *
371 * @return
372 */
373 public Exception getFailure() {
374 return failure;
375 } // getFailure
376 } // WSDLRunnable
377
378 /**
379 * Call this method if your WSDL document has already been parsed as an XML DOM document.
380 *
381 * @param context context This is directory context for the Document. If the Document were from file "/x/y/z.wsdl" then the context could be "/x/y" (even "/x/y/z.wsdl" would work). If context is null, then the context becomes the current directory.
382 * @param doc doc This is the XML Document containing the WSDL.
383 * @throws IOException
384 * @throws SAXException
385 * @throws WSDLException
386 * @throws ParserConfigurationException
387 */
388 public void run(String context, Document doc)
389 throws IOException, SAXException, WSDLException,
390 ParserConfigurationException {
391
392 if (getFactory() == null) {
393 setFactory(new NoopFactory());
394 }
395
396 symbolTable = new SymbolTable(genFactory.getBaseTypeMapping(), imports,
397 verbose, nowrap);
398
399 symbolTable.populate(context, doc);
400 generate(symbolTable);
401 } // run
402
403 /**
404 * Method sanityCheck
405 *
406 * @param symbolTable
407 */
408 protected void sanityCheck(SymbolTable symbolTable) {
409
410 // do nothing.
411 }
412
413 /**
414 * Method generate
415 *
416 * @param symbolTable
417 * @throws IOException
418 */
419 private void generate(SymbolTable symbolTable) throws IOException {
420
421 sanityCheck(symbolTable);
422
423 Definition def = symbolTable.getDefinition();
424
425 genFactory.generatorPass(def, symbolTable);
426
427 if (isDebug()) {
428 symbolTable.dump(System.out);
429 }
430
431 // Generate bindings for types
432 generateTypes(symbolTable);
433
434 Iterator it = symbolTable.getHashMap().values().iterator();
435
436 while (it.hasNext()) {
437 Vector v = (Vector) it.next();
438
439 for (int i = 0; i < v.size(); ++i) {
440 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
441 Generator gen = null;
442
443 if (entry instanceof MessageEntry) {
444 gen = genFactory.getGenerator(
445 ((MessageEntry) entry).getMessage(), symbolTable);
446 } else if (entry instanceof PortTypeEntry) {
447 PortTypeEntry pEntry = (PortTypeEntry) entry;
448
449 // If the portType is undefined, then we're parsing a Definition
450 // that didn't contain a portType, merely a binding that referred
451 // to a non-existent port type. Don't bother writing it.
452 if (pEntry.getPortType().isUndefined()) {
453 continue;
454 }
455
456 gen = genFactory.getGenerator(pEntry.getPortType(),
457 symbolTable);
458 } else if (entry instanceof BindingEntry) {
459 BindingEntry bEntry = (BindingEntry) entry;
460 Binding binding = bEntry.getBinding();
461
462 // If the binding is undefined, then we're parsing a Definition
463 // that didn't contain a binding, merely a service that referred
464 // to a non-existent binding. Don't bother writing it.
465 if (binding.isUndefined() || !bEntry.isReferenced()) {
466 continue;
467 }
468
469 gen = genFactory.getGenerator(binding, symbolTable);
470 } else if (entry instanceof ServiceEntry) {
471 gen = genFactory.getGenerator(
472 ((ServiceEntry) entry).getService(), symbolTable);
473 }
474
475 if (gen != null) {
476 gen.generate();
477 }
478 }
479 }
480
481 // Output extra stuff (deployment files and faults)
482 // outside of the recursive emit method.
483 Generator gen = genFactory.getGenerator(def, symbolTable);
484
485 gen.generate();
486 } // generate
487
488 /**
489 * Generate bindings (classes and class holders) for the complex types.
490 * If generating serverside (skeleton) spit out beanmappings
491 *
492 * @param symbolTable
493 * @throws IOException
494 */
495 private void generateTypes(SymbolTable symbolTable) throws IOException {
496
497 Map elements = symbolTable.getElementIndex();
498 Collection elementCollection = elements.values();
499 for (Iterator i = elementCollection.iterator(); i.hasNext(); ) {
500 TypeEntry type = (TypeEntry) i.next();
501
502 // Write out the type if and only if:
503 // - we found its definition (getNode())
504 // - it is referenced
505 // - it is not a base type or an attributeGroup or xs:group
506 // - it is a Type (not an Element) or a CollectionElement
507 // (Note that types that are arrays are passed to getGenerator
508 // because they may require a Holder)
509 // A CollectionElement is an array that might need a holder
510 boolean isType = ((type instanceof Type)
511 || (type instanceof CollectionElement));
512
513 if ((type.getNode() != null)
514 && !Utils.isXsNode(type.getNode(), "attributeGroup")
515 && !Utils.isXsNode(type.getNode(), "group")
516 && type.isReferenced() && isType
517 && (type.getBaseType() == null)) {
518 Generator gen = genFactory.getGenerator(type, symbolTable);
519
520 gen.generate();
521 }
522 }
523
524 Map types = symbolTable.getTypeIndex();
525 Collection typeCollection = types.values();
526 for (Iterator i = typeCollection.iterator(); i.hasNext(); ) {
527 TypeEntry type = (TypeEntry) i.next();
528
529 // Write out the type if and only if:
530 // - we found its definition (getNode())
531 // - it is referenced
532 // - it is not a base type or an attributeGroup or xs:group
533 // - it is a Type (not an Element) or a CollectionElement
534 // (Note that types that are arrays are passed to getGenerator
535 // because they may require a Holder)
536 // A CollectionElement is an array that might need a holder
537 boolean isType = ((type instanceof Type)
538 || (type instanceof CollectionElement));
539
540 if ((type.getNode() != null)
541 && !Utils.isXsNode(type.getNode(), "attributeGroup")
542 && !Utils.isXsNode(type.getNode(), "group")
543 && type.isReferenced() && isType
544 && (type.getBaseType() == null)) {
545 Generator gen = genFactory.getGenerator(type, symbolTable);
546
547 gen.generate();
548 }
549 }
550 } // generateTypes
551 } // class Parser