KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > axis > wsdl > toJava > JavaGeneratorFactory


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.toJava;
17
18 import org.apache.axis.components.logger.LogFactory;
19 import org.apache.axis.utils.JavaUtils;
20 import org.apache.axis.utils.Messages;
21 import org.apache.axis.wsdl.gen.Generator;
22 import org.apache.axis.wsdl.gen.GeneratorFactory;
23 import org.apache.axis.wsdl.gen.NoopGenerator;
24 import org.apache.axis.wsdl.symbolTable.BaseTypeMapping;
25 import org.apache.axis.wsdl.symbolTable.BindingEntry;
26 import org.apache.axis.wsdl.symbolTable.ContainedAttribute;
27 import org.apache.axis.wsdl.symbolTable.Element;
28 import org.apache.axis.wsdl.symbolTable.ElementDecl;
29 import org.apache.axis.wsdl.symbolTable.FaultInfo;
30 import org.apache.axis.wsdl.symbolTable.MessageEntry;
31 import org.apache.axis.wsdl.symbolTable.Parameter;
32 import org.apache.axis.wsdl.symbolTable.Parameters;
33 import org.apache.axis.wsdl.symbolTable.PortTypeEntry;
34 import org.apache.axis.wsdl.symbolTable.SchemaUtils;
35 import org.apache.axis.wsdl.symbolTable.ServiceEntry;
36 import org.apache.axis.wsdl.symbolTable.SymTabEntry;
37 import org.apache.axis.wsdl.symbolTable.SymbolTable;
38 import org.apache.axis.wsdl.symbolTable.Type;
39 import org.apache.axis.wsdl.symbolTable.TypeEntry;
40 import org.apache.commons.logging.Log;
41
42 import javax.wsdl.Binding;
43 import javax.wsdl.Definition;
44 import javax.wsdl.Fault;
45 import javax.wsdl.Message;
46 import javax.wsdl.Operation;
47 import javax.wsdl.OperationType;
48 import javax.wsdl.Port;
49 import javax.wsdl.PortType;
50 import javax.wsdl.Service;
51 import javax.xml.namespace.QName JavaDoc;
52 import javax.xml.rpc.holders.BooleanHolder JavaDoc;
53 import java.io.IOException JavaDoc;
54 import java.lang.reflect.Constructor JavaDoc;
55 import java.util.ArrayList JavaDoc;
56 import java.util.HashMap JavaDoc;
57 import java.util.HashSet JavaDoc;
58 import java.util.Iterator JavaDoc;
59 import java.util.List JavaDoc;
60 import java.util.Map JavaDoc;
61 import java.util.Vector JavaDoc;
62
63 /**
64  * This is Wsdl2java's implementation of the GeneratorFactory
65  */

66 public class JavaGeneratorFactory implements GeneratorFactory {
67     private static final Log log_ =
68         LogFactory.getLog(JavaGeneratorFactory.class.getName());
69
70     /** Field emitter */
71     protected Emitter emitter;
72
73     /** Field symbolTable */
74     protected SymbolTable symbolTable;
75
76     /** Field COMPLEX_TYPE_FAULT */
77     public static String JavaDoc COMPLEX_TYPE_FAULT = "ComplexTypeFault";
78
79     /** Field EXCEPTION_CLASS_NAME */
80     public static String JavaDoc EXCEPTION_CLASS_NAME = "ExceptionClassName";
81
82     /** Field EXCEPTION_DATA_TYPE */
83     public static String JavaDoc EXCEPTION_DATA_TYPE = "ExceptionDataType";
84     
85     /* Name suffixes for collision */
86     private static final String JavaDoc SERVICE_SUFFIX = "_Service";
87     private static final String JavaDoc PORT_TYPE_SUFFIX = "_PortType"; // "_Port" (Axis classic) --> "_PortType" (JAX-RPC 1.1)
88
private static final String JavaDoc TYPE_SUFFIX = "_Type";
89     private static final String JavaDoc ELEMENT_SUFFIX = "_Element"; // "_ElemType (Axis classic) --> "_Element" (JAX-RPC 1.1)
90
private static final String JavaDoc EXCEPTION_SUFFIX = "_Exception";
91     private static final String JavaDoc BINDING_SUFFIX = "_Binding";
92
93
94     /**
95      * Default constructor. Note that this class is unusable until setEmitter
96      * is called.
97      */

98     public JavaGeneratorFactory() {
99         addGenerators();
100     } // ctor
101

102     /**
103      * Constructor JavaGeneratorFactory
104      *
105      * @param emitter
106      */

107     public JavaGeneratorFactory(Emitter emitter) {
108
109         this.emitter = emitter;
110
111         addGenerators();
112     } // ctor
113

114     /**
115      * Method setEmitter
116      *
117      * @param emitter
118      */

119     public void setEmitter(Emitter emitter) {
120         this.emitter = emitter;
121     } // setEmitter
122

123     /**
124      * Method addGenerators
125      */

126     private void addGenerators() {
127
128         addMessageGenerators();
129         addPortTypeGenerators();
130         addBindingGenerators();
131         addServiceGenerators();
132         addTypeGenerators();
133         addDefinitionGenerators();
134     } // addGenerators
135

136     /**
137      * These addXXXGenerators are called by the constructor.
138      * If an extender of this factory wants to CHANGE the set
139      * of generators that are called per WSDL construct, they
140      * should override these addXXXGenerators methods. If all
141      * an extender wants to do is ADD a generator, then the
142      * extension should simply call addGenerator.
143      * (NOTE: It doesn't quite work this way, yet. Only the
144      * Definition generators fit this model at this point in
145      * time.)
146      */

147     protected void addMessageGenerators() {
148     } // addMessageGenerators
149

150     /**
151      * Method addPortTypeGenerators
152      */

153     protected void addPortTypeGenerators() {
154     } // addPortTypeGenerators
155

156     /**
157      * Method addBindingGenerators
158      */

159     protected void addBindingGenerators() {
160     } // addBindingGenerators
161

162     /**
163      * Method addServiceGenerators
164      */

165     protected void addServiceGenerators() {
166     } // addServiceGenerators
167

168     /**
169      * Method addTypeGenerators
170      */

171     protected void addTypeGenerators() {
172     } // addTypeGenerators
173

174     /**
175      * Method addDefinitionGenerators
176      */

177     protected void addDefinitionGenerators() {
178
179         addGenerator(Definition.class, JavaDefinitionWriter.class); // for faults
180
addGenerator(Definition.class,
181                 JavaDeployWriter.class); // for deploy.wsdd
182
addGenerator(Definition.class,
183                 JavaUndeployWriter.class); // for undeploy.wsdd
184
addGenerator(Definition.class,
185                 JavaBuildFileWriter.class); //add a build file writer
186

187     } // addDefinitionGenerators
188

189
190     /**
191      * Do the Wsdl2java generator pass:
192      * - resolve name clashes
193      * - construct signatures
194      *
195      * @param def
196      * @param symbolTable
197      */

198     public void generatorPass(Definition def, SymbolTable symbolTable) {
199
200         this.symbolTable = symbolTable;
201
202         javifyNames(symbolTable);
203         setFaultContext(symbolTable);
204         resolveNameClashes(symbolTable);
205         determineInterfaceNames(symbolTable);
206
207         if (emitter.isAllWanted()) {
208             setAllReferencesToTrue();
209         } else {
210             ignoreNonSOAPBindings(symbolTable);
211         }
212
213         constructSignatures(symbolTable);
214         determineIfHoldersNeeded(symbolTable);
215     } // generatorPass
216

217     /** Since Wsdl2java doesn't emit anything for Messages, return the No-op generator. */
218     private Writers messageWriters = new Writers();
219
220     /**
221      * Method getGenerator
222      *
223      * @param message
224      * @param symbolTable
225      * @return
226      */

227     public Generator getGenerator(Message message, SymbolTable symbolTable) {
228         if (include(message.getQName())) {
229             MessageEntry mEntry = symbolTable.getMessageEntry(message.getQName());
230             messageWriters.addStuff(new NoopGenerator(), mEntry, symbolTable);
231             return messageWriters;
232         }
233         else {
234             return new NoopGenerator();
235         }
236     } // getGenerator
237

238     /** Return Wsdl2java's JavaPortTypeWriter object. */
239     private Writers portTypeWriters = new Writers();
240
241     /**
242      * Method getGenerator
243      *
244      * @param portType
245      * @param symbolTable
246      * @return
247      */

248     public Generator getGenerator(PortType portType, SymbolTable symbolTable) {
249         if (include(portType.getQName())) {
250             PortTypeEntry ptEntry =
251                     symbolTable.getPortTypeEntry(portType.getQName());
252             portTypeWriters.addStuff(new NoopGenerator(), ptEntry, symbolTable);
253             return portTypeWriters;
254         }
255         else {
256             return new NoopGenerator();
257         }
258     } // getGenerator
259

260     /** Return Wsdl2java's JavaBindingWriter object. */
261     protected Writers bindingWriters = new Writers();
262
263     /**
264      * Method getGenerator
265      *
266      * @param binding
267      * @param symbolTable
268      * @return
269      */

270     public Generator getGenerator(Binding binding, SymbolTable symbolTable) {
271         if (include(binding.getQName())) {
272             Generator writer = new JavaBindingWriter(emitter, binding,
273                     symbolTable);
274             BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
275             bindingWriters.addStuff(writer, bEntry, symbolTable);
276             return bindingWriters;
277         }
278         else {
279             return new NoopGenerator();
280         }
281     } // getGenerator
282

283     /** Return Wsdl2java's JavaServiceWriter object. */
284     protected Writers serviceWriters = new Writers();
285
286     /**
287      * Method getGenerator
288      *
289      * @param service
290      * @param symbolTable
291      * @return
292      */

293     public Generator getGenerator(Service service, SymbolTable symbolTable) {
294         if (include(service.getQName())) {
295             Generator writer = new JavaServiceWriter(emitter, service,
296                     symbolTable);
297             ServiceEntry sEntry = symbolTable.getServiceEntry(service.getQName());
298             serviceWriters.addStuff(writer, sEntry, symbolTable);
299             return serviceWriters;
300         }
301         else {
302             return new NoopGenerator();
303         }
304     } // getGenerator
305

306     /** Return Wsdl2java's JavaTypeWriter object. */
307     private Writers typeWriters = new Writers();
308
309     /**
310      * Method getGenerator
311      *
312      * @param type
313      * @param symbolTable
314      * @return
315      */

316     public Generator getGenerator(TypeEntry type, SymbolTable symbolTable) {
317         if (include(type.getQName())) {
318             Generator writer = new JavaTypeWriter(emitter, type, symbolTable);
319             typeWriters.addStuff(writer, type, symbolTable);
320             return typeWriters;
321         }
322         else {
323             return new NoopGenerator();
324         }
325     } // getGenerator
326

327     /** Return Wsdl2java's JavaDefinitionWriter object. */
328     private Writers defWriters = new Writers();
329
330     /**
331      * Method getGenerator
332      *
333      * @param definition
334      * @param symbolTable
335      * @return
336      */

337     public Generator getGenerator(Definition definition,
338                                   SymbolTable symbolTable) {
339         if (include(definition.getQName())) {
340             defWriters.addStuff(null, definition, symbolTable);
341             return defWriters;
342         }
343         else {
344             return new NoopGenerator();
345         }
346     } // getGenerator
347

348     // Hack class just to play with the idea of adding writers
349

350     /**
351      * Class Writers
352      *
353      * @version %I%, %G%
354      */

355     protected class Writers implements Generator {
356
357         /** Field writers */
358         Vector JavaDoc writers = new Vector JavaDoc();
359
360         /** Field symbolTable */
361         SymbolTable symbolTable = null;
362
363         /** Field baseWriter */
364         Generator baseWriter = null;
365
366         // entry or def, but not both, will be a parameter.
367

368         /** Field entry */
369         SymTabEntry entry = null;
370
371         /** Field def */
372         Definition def = null;
373
374         /**
375          * Method addGenerator
376          *
377          * @param writer
378          */

379         public void addGenerator(Class JavaDoc writer) {
380             writers.add(writer);
381         } // addWriter
382

383         /**
384          * Method addStuff
385          *
386          * @param baseWriter
387          * @param entry
388          * @param symbolTable
389          */

390         public void addStuff(Generator baseWriter, SymTabEntry entry,
391                              SymbolTable symbolTable) {
392
393             this.baseWriter = baseWriter;
394             this.entry = entry;
395             this.symbolTable = symbolTable;
396         } // addStuff
397

398         /**
399          * Method addStuff
400          *
401          * @param baseWriter
402          * @param def
403          * @param symbolTable
404          */

405         public void addStuff(Generator baseWriter, Definition def,
406                              SymbolTable symbolTable) {
407
408             this.baseWriter = baseWriter;
409             this.def = def;
410             this.symbolTable = symbolTable;
411         } // addStuff
412

413         /**
414          * Method generate
415          *
416          * @throws IOException
417          */

418         public void generate() throws IOException JavaDoc {
419
420             if (baseWriter != null) {
421                 baseWriter.generate();
422             }
423
424             Class JavaDoc[] formalArgs;
425             Object JavaDoc[] actualArgs;
426
427             if (entry != null) {
428                 formalArgs = new Class JavaDoc[]{Emitter.class, entry.getClass(),
429                                          SymbolTable.class};
430                 actualArgs = new Object JavaDoc[]{emitter, entry, symbolTable};
431             } else {
432                 formalArgs = new Class JavaDoc[]{Emitter.class, Definition.class,
433                                          SymbolTable.class};
434                 actualArgs = new Object JavaDoc[]{emitter, def, symbolTable};
435             }
436
437             for (int i = 0; i < writers.size(); ++i) {
438                 Class JavaDoc wClass = (Class JavaDoc) writers.get(i);
439                 Generator gen;
440
441                 try {
442                     Constructor JavaDoc ctor = wClass.getConstructor(formalArgs);
443
444                     gen = (Generator) ctor.newInstance(actualArgs);
445                 } catch (Throwable JavaDoc t) {
446                     throw new IOException JavaDoc(Messages.getMessage("exception01",
447                             t.getMessage()));
448                 }
449
450                 gen.generate();
451             }
452         } // generate
453
} // class Writers
454

455     /**
456      * Method addGenerator
457      *
458      * @param wsdlClass
459      * @param generator
460      */

461     public void addGenerator(Class JavaDoc wsdlClass, Class JavaDoc generator) {
462
463         // This is just a hack right now... it just works with Service
464
if (Message.class.isAssignableFrom(wsdlClass)) {
465             messageWriters.addGenerator(generator);
466         } else if (PortType.class.isAssignableFrom(wsdlClass)) {
467             portTypeWriters.addGenerator(generator);
468         } else if (Binding.class.isAssignableFrom(wsdlClass)) {
469             bindingWriters.addGenerator(generator);
470         } else if (Service.class.isAssignableFrom(wsdlClass)) {
471             serviceWriters.addGenerator(generator);
472         } else if (TypeEntry.class.isAssignableFrom(wsdlClass)) {
473             typeWriters.addGenerator(generator);
474         } else if (Definition.class.isAssignableFrom(wsdlClass)) {
475             defWriters.addGenerator(generator);
476         }
477     } // addGenerator
478

479     /**
480      * Fill in the names of each SymTabEntry with the javaified name.
481      * Note: This method also ensures that anonymous types are
482      * given unique java type names.
483      *
484      * @param symbolTable
485      */

486     protected void javifyNames(SymbolTable symbolTable) {
487
488         int uniqueNum = 0;
489         HashMap JavaDoc anonQNames = new HashMap JavaDoc();
490         Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
491
492         while (it.hasNext()) {
493             Vector JavaDoc v = (Vector JavaDoc) it.next();
494
495             for (int i = 0; i < v.size(); ++i) {
496                 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
497
498                 if (entry.getName() != null) {
499                     continue;
500                 }
501
502                 // Use the type or the referenced type's QName to generate the java name.
503
if (entry instanceof TypeEntry) {
504                     uniqueNum = javifyTypeEntryName(symbolTable, (TypeEntry) entry, anonQNames, uniqueNum);
505                 }
506
507                 // If it is not a type, then use this entry's QName to
508
// generate its name.
509
else {
510                     entry.setName(emitter.getJavaName(entry.getQName()));
511                 }
512             }
513         }
514     } // javifyNames
515

516     /** Refactored to call recursively for JAX-RPC 1.1 spec 4.2.5. */
517     protected int javifyTypeEntryName(SymbolTable symbolTable, TypeEntry entry, HashMap JavaDoc anonQNames, int uniqueNum) {
518         TypeEntry tEntry = entry;
519         String JavaDoc dims = tEntry.getDimensions();
520         TypeEntry refType = tEntry.getRefType();
521         while (refType != null) {
522             tEntry = refType;
523             dims += tEntry.getDimensions();
524             refType = tEntry.getRefType();
525         }
526
527         TypeEntry te = tEntry;
528         while (te != null) {
529             TypeEntry base = SchemaUtils.getBaseType(te, symbolTable);
530             if (base == null)
531                 break;
532
533             uniqueNum = javifyTypeEntryName(symbolTable, base, anonQNames, uniqueNum);
534
535             if (Utils.getEnumerationBaseAndValues(te.getNode(), symbolTable) == null
536                     &&SchemaUtils.getComplexElementExtensionBase(te.getNode(), symbolTable) == null
537                     && te.getContainedAttributes() == null) {
538                 if(!SchemaUtils.isSimpleTypeWithUnion(te.getNode())) {
539                     if (base.isSimpleType()) {
540                         // Case 1:
541
// <simpleType name="mySimpleStringType">
542
// <restriction base="xs:string">
543
// </restriction>
544
// </simpleType>
545
te.setSimpleType(true);
546                         te.setName(base.getName());
547                         te.setRefType(base);
548                     }
549     
550                     if (base.isBaseType()) {
551                         // Case 2:
552
// <simpleType name="FooString">
553
// <restriction base="foo:mySimpleStringType">
554
// </restriction>
555
// </simpleType>
556
te.setBaseType(true);
557                         te.setName(base.getName());
558                         te.setRefType(base);
559                     }
560                 }
561             }
562
563             if (!te.isSimpleType())
564                 break;
565
566             te = base;
567         }
568
569         // Need to javify the ref'd TypeEntry if it was not
570
// already processed
571
if (tEntry.getName() == null) {
572             boolean processed = false; // true if the java name is already determined
573
// Get the QName of the ref'd TypeEntry, which
574
// is will be used to javify the name
575
QName JavaDoc typeQName = tEntry.getQName();
576
577             // In case of <xsd:list itemType="...">,
578
// set typeQName to the value of the itemType attribute.
579
QName JavaDoc itemType = SchemaUtils.getListItemType(tEntry.getNode());
580             if (itemType != null) {
581                 // Get the typeEntry so we know the absolute base type
582
TypeEntry itemEntry = symbolTable.getTypeEntry(itemType, false);
583         // TODO - If the itemEntry is not found, we need to throw
584
// an exception. "Item is referenced, but not defined"
585
javifyTypeEntryName(symbolTable, itemEntry, anonQNames, uniqueNum);
586                 // Grab the referenced type, If it's there.
587
TypeEntry refedEntry = itemEntry.getRefType();
588                 QName JavaDoc baseName = refedEntry == null ? itemEntry.getQName() :
589                         refedEntry.getQName();
590                 typeQName = new QName JavaDoc(baseName.getNamespaceURI(),
591                                         baseName.getLocalPart() + "[]");
592             }
593             
594             if (emitter.isDeploy()) {
595                 Class JavaDoc class1 = (Class JavaDoc) emitter.getQName2ClassMap().get(typeQName);
596                 if (class1 != null && !class1.isArray()) {
597                     tEntry.setName(getJavaClassName(class1));
598                     processed = true;
599                 }
600             }
601             
602             if (!processed) {
603                 if ((typeQName.getLocalPart().
604                         indexOf(SymbolTable.ANON_TOKEN) < 0)) {
605                     // Normal Case: The ref'd type is not anonymous
606
// Simply construct the java name from
607
// the qName
608
tEntry.setName(emitter.getJavaName(typeQName));
609                 } else {
610                     // This is an anonymous type name.
611
// Axis uses '>' as a nesting token to generate
612
// unique qnames for anonymous types.
613
// Only consider the localName after the last '>'
614
// when generating the java name
615
// String localName = typeQName.getLocalPart();
616
// localName =
617
// localName.substring(
618
// localName.lastIndexOf(
619
// SymbolTable.ANON_TOKEN)+1);
620
// typeQName = new QName(typeQName.getNamespaceURI(),
621
// localName);
622
String JavaDoc localName = typeQName.getLocalPart();
623     
624                     // Check to see if this is an anonymous type,
625
// if it is, replace Axis' ANON_TOKEN with
626
// an underscore to make sure we don't run
627
// into name collisions with similarly named
628
// non-anonymous types
629
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(localName);
630                     int aidx;
631     
632                     while ((aidx = sb.toString().indexOf(SymbolTable.ANON_TOKEN)) > -1) {
633                         sb.replace(aidx, aidx + SymbolTable.ANON_TOKEN.length(), "");
634                         char c = sb.charAt(aidx);
635                         if (Character.isLetter(c) && Character.isLowerCase(c)) {
636                             sb.setCharAt(aidx, Character.toUpperCase(c));
637                         }
638                     }
639                             
640                     localName = sb.toString();
641                     typeQName = new QName JavaDoc(typeQName.getNamespaceURI(),
642                             localName);
643     
644                     if (emitter.isTypeCollisionProtection() &&
645                             !emitter.getNamespaceExcludes().contains(new NamespaceSelector(typeQName.getNamespaceURI()))) {
646                         // If there is already an existing type,
647
// there will be a collision.
648
// If there is an existing anon type,
649
// there will be a collision.
650
// In both cases, mangle the name.
651
if (symbolTable.getType(typeQName) != null ||
652                                 anonQNames.get(typeQName) != null) {
653                             localName += "Type" + uniqueNum++;
654                             typeQName =
655                                 new QName JavaDoc(typeQName.getNamespaceURI(),
656                                           localName);
657                         }
658                         
659                         anonQNames.put(typeQName, typeQName);
660                     }
661     
662                     // Now set the name with the constructed qname
663
tEntry.setName(emitter.getJavaName(typeQName));
664                 }
665             } // if (!processed)
666

667             Vector JavaDoc elements = tEntry.getContainedElements();
668             if (elements != null) {
669                 for (int i = 0; i < elements.size(); i++) {
670                     ElementDecl elem = (ElementDecl) elements.get(i);
671                     String JavaDoc varName = emitter.getJavaVariableName(typeQName, elem.getQName(), true);
672                     elem.setName(varName);
673                 }
674             }
675             
676             Vector JavaDoc attributes = tEntry.getContainedAttributes();
677             if (attributes != null) {
678                 for (int i = 0; i < attributes.size(); i++) {
679                     ContainedAttribute attr = (ContainedAttribute) attributes.get(i);
680                     String JavaDoc varName = emitter.getJavaVariableName(typeQName, attr.getQName(), false);
681                     attr.setName(varName);
682                 }
683             }
684         }
685
686         // Set the entry with the same name as the ref'd entry
687
// but add the appropriate amount of dimensions
688
entry.setName(tEntry.getName() + dims);
689
690         return uniqueNum;
691     }
692     
693     /**
694      * Gets class name from Java class.
695      * If the class is an array, get its component type's name
696      * @param clazz a java class
697      * @return the class name in string
698      */

699     private static String JavaDoc getJavaClassName(Class JavaDoc clazz) {
700         Class JavaDoc class1 = clazz;
701         
702         while (class1.isArray()) {
703             class1 = class1.getComponentType();
704         }
705         
706         String JavaDoc name = class1.getName();
707         name.replace('$', '.');
708         return name;
709     }
710
711     /**
712      * setFaultContext:
713      * Processes the symbol table and sets the COMPLEX_TYPE_FAULT
714      * on each TypeEntry that is a complexType and is referenced in
715      * a fault message. TypeEntries that are the base or derived
716      * from such a TypeEntry are also marked with COMPLEX_TYPE_FAULT.
717      * The containing MessageEntry is marked with cOMPLEX_TYPE_FAULT, and
718      * all MessageEntries for faults are tagged with the
719      * EXCEPTION_CLASS_NAME variable, which indicates the java exception
720      * class name.
721      *
722      * @param symbolTable SymbolTable
723      */

724     private void setFaultContext(SymbolTable symbolTable) {
725
726         Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
727
728         while (it.hasNext()) {
729             Vector JavaDoc v = (Vector JavaDoc) it.next();
730
731             for (int i = 0; i < v.size(); ++i) {
732                 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
733
734                 // Inspect each BindingEntry in the Symbol Table
735
if (entry instanceof BindingEntry) {
736                     BindingEntry bEntry = (BindingEntry) entry;
737                     HashMap JavaDoc allOpFaults = bEntry.getFaults();
738                     Iterator JavaDoc ops = allOpFaults.values().iterator();
739
740                     // set the context for all faults for this binding.
741
while (ops.hasNext()) {
742                         ArrayList JavaDoc faults = (ArrayList JavaDoc) ops.next();
743
744                         for (int j = 0; j < faults.size(); ++j) {
745                             FaultInfo info = (FaultInfo) faults.get(j);
746
747                             setFaultContext(info, symbolTable);
748                         }
749                     }
750                 }
751             }
752         }
753     } // setFaultContext
754

755     /**
756      * setFaultContext:
757      * Helper routine for the setFaultContext method above.
758      * Examines the indicated fault and sets COMPLEX_TYPE_FAULT
759      * EXCEPTION_DATA_TYPE and EXCEPTION_CLASS_NAME as appropriate.
760      *
761      * @param fault FaultInfo to analyze
762      * @param symbolTable SymbolTable
763      */

764     private void setFaultContext(FaultInfo fault, SymbolTable symbolTable) {
765
766         QName JavaDoc faultXmlType = null;
767         Vector JavaDoc parts = new Vector JavaDoc();
768
769         // Get the parts of the fault's message.
770
// An IOException is thrown if the parts cannot be
771
// processed. Skip such parts for this analysis
772
try {
773             symbolTable.getParametersFromParts(
774                     parts, fault.getMessage().getOrderedParts(null), false,
775                     fault.getName(), null);
776         } catch (IOException JavaDoc e) {
777         }
778
779         // Inspect each TypeEntry referenced in a Fault Message Part
780
String JavaDoc exceptionClassName = null;
781
782         for (int j = 0; j < parts.size(); j++) {
783             TypeEntry te = ((Parameter) (parts.elementAt(j))).getType();
784
785             // If the TypeEntry is an element, advance to the type.
786
// This occurs if the message part us