KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Axis" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation. For more
52  * information on the Apache Software Foundation, please see
53  * <http://www.apache.org/>.
54  */

55 package org.jboss.axis.wsdl.toJava;
56
57 import org.jboss.axis.encoding.DefaultTypeMappingImpl;
58 import org.jboss.axis.encoding.TypeMapping;
59 import org.jboss.axis.utils.JavaUtils;
60 import org.jboss.axis.utils.Messages;
61 import org.jboss.axis.wsdl.gen.Generator;
62 import org.jboss.axis.wsdl.gen.GeneratorFactory;
63 import org.jboss.axis.wsdl.gen.NoopGenerator;
64 import org.jboss.axis.wsdl.symbolTable.BaseTypeMapping;
65 import org.jboss.axis.wsdl.symbolTable.BindingEntry;
66 import org.jboss.axis.wsdl.symbolTable.Element;
67 import org.jboss.axis.wsdl.symbolTable.FaultInfo;
68 import org.jboss.axis.wsdl.symbolTable.MessageEntry;
69 import org.jboss.axis.wsdl.symbolTable.Parameter;
70 import org.jboss.axis.wsdl.symbolTable.Parameters;
71 import org.jboss.axis.wsdl.symbolTable.PortTypeEntry;
72 import org.jboss.axis.wsdl.symbolTable.SchemaUtils;
73 import org.jboss.axis.wsdl.symbolTable.ServiceEntry;
74 import org.jboss.axis.wsdl.symbolTable.SymTabEntry;
75 import org.jboss.axis.wsdl.symbolTable.SymbolTable;
76 import org.jboss.axis.wsdl.symbolTable.Type;
77 import org.jboss.axis.wsdl.symbolTable.TypeEntry;
78
79 import javax.wsdl.Binding;
80 import javax.wsdl.Definition;
81 import javax.wsdl.Fault;
82 import javax.wsdl.Message;
83 import javax.wsdl.Operation;
84 import javax.wsdl.OperationType;
85 import javax.wsdl.PortType;
86 import javax.wsdl.Service;
87 import javax.xml.namespace.QName JavaDoc;
88 import javax.xml.rpc.holders.BooleanHolder JavaDoc;
89 import java.io.IOException JavaDoc;
90 import java.lang.reflect.Constructor JavaDoc;
91 import java.util.ArrayList JavaDoc;
92 import java.util.HashMap JavaDoc;
93 import java.util.HashSet JavaDoc;
94 import java.util.Iterator JavaDoc;
95 import java.util.Map JavaDoc;
96 import java.util.Vector JavaDoc;
97
98 /**
99  * This is Wsdl2java's implementation of the GeneratorFactory
100  */

101
102 public class JavaGeneratorFactory implements GeneratorFactory
103 {
104    protected Emitter emitter;
105    protected SymbolTable symbolTable;
106
107    public static String JavaDoc COMPLEX_TYPE_FAULT = "ComplexTypeFault";
108    public static String JavaDoc EXCEPTION_CLASS_NAME = "ExceptionClassName";
109    public static String JavaDoc EXCEPTION_DATA_TYPE = "ExceptionDataType";
110
111    /**
112     * Default constructor. Note that this class is unusable until setEmitter
113     * is called.
114     */

115
116    public JavaGeneratorFactory()
117    {
118       addGenerators();
119    } // ctor
120

121    public JavaGeneratorFactory(Emitter emitter)
122    {
123       this.emitter = emitter;
124       addGenerators();
125    } // ctor
126

127    public void setEmitter(Emitter emitter)
128    {
129       this.emitter = emitter;
130    } // setEmitter
131

132    private void addGenerators()
133    {
134       addMessageGenerators();
135       addPortTypeGenerators();
136       addBindingGenerators();
137       addServiceGenerators();
138       addTypeGenerators();
139       addDefinitionGenerators();
140    } // addGenerators
141

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

153    protected void addMessageGenerators()
154    {
155    } // addMessageGenerators
156

157    protected void addPortTypeGenerators()
158    {
159    } // addPortTypeGenerators
160

161    protected void addBindingGenerators()
162    {
163    } // addBindingGenerators
164

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

169    protected void addTypeGenerators()
170    {
171    } // addTypeGenerators
172

173    protected void addDefinitionGenerators()
174    {
175       addGenerator(Definition.class, JavaDefinitionWriter.class); // for faults
176
addGenerator(Definition.class, JavaDeployWriter.class); // for deploy.wsdd
177
addGenerator(Definition.class, JavaUndeployWriter.class); // for undeploy.wsdd
178
} // addDefinitionGenerators
179

180    /**
181     * Do the Wsdl2java generator pass:
182     * - resolve name clashes
183     * - construct signatures
184     */

185    public void generatorPass(Definition def, SymbolTable symbolTable)
186    {
187       this.symbolTable = symbolTable;
188       javifyNames(symbolTable);
189       setFaultContext(symbolTable);
190       resolveNameClashes(symbolTable);
191       determineInterfaceNames(symbolTable);
192       if (emitter.isAllWanted())
193       {
194          setAllReferencesToTrue();
195       }
196       else
197       {
198          ignoreNonSOAPBindings(symbolTable);
199       }
200       constructSignatures(symbolTable);
201       determineIfHoldersNeeded(symbolTable);
202    } // generatorPass
203

204    /**
205     * Since Wsdl2java doesn't emit anything for Messages, return the No-op generator.
206     */

207    private Writers messageWriters = new Writers();
208
209    public Generator getGenerator(Message message, SymbolTable symbolTable)
210    {
211       MessageEntry mEntry = symbolTable.getMessageEntry(message.getQName());
212       messageWriters.addStuff(new NoopGenerator(), mEntry, symbolTable);
213       return messageWriters;
214    } // getGenerator
215

216    /**
217     * Return Wsdl2java's JavaPortTypeWriter object.
218     */

219    private Writers portTypeWriters = new Writers();
220
221    public Generator getGenerator(PortType portType, SymbolTable symbolTable)
222    {
223       PortTypeEntry ptEntry = symbolTable.getPortTypeEntry(portType.getQName());
224       portTypeWriters.addStuff(new NoopGenerator(), ptEntry, symbolTable);
225       return portTypeWriters;
226    } // getGenerator
227

228    /**
229     * Return Wsdl2java's JavaBindingWriter object.
230     */

231    protected Writers bindingWriters = new Writers();
232
233    public Generator getGenerator(Binding binding, SymbolTable symbolTable)
234    {
235       Generator writer = new JavaBindingWriter(emitter, binding, symbolTable);
236       BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
237       bindingWriters.addStuff(writer, bEntry, symbolTable);
238       return bindingWriters;
239    } // getGenerator
240

241    /**
242     * Return Wsdl2java's JavaServiceWriter object.
243     */

244    protected Writers serviceWriters = new Writers();
245
246    public Generator getGenerator(Service service, SymbolTable symbolTable)
247    {
248       Generator writer = new JavaServiceWriter(emitter, service, symbolTable);
249       ServiceEntry sEntry = symbolTable.getServiceEntry(service.getQName());
250       serviceWriters.addStuff(writer, sEntry, symbolTable);
251       return serviceWriters;
252    } // getGenerator
253

254    /**
255     * Return Wsdl2java's JavaTypeWriter object.
256     */

257    private Writers typeWriters = new Writers();
258
259    public Generator getGenerator(TypeEntry type, SymbolTable symbolTable)
260    {
261       Generator writer = new JavaTypeWriter(emitter, type, symbolTable);
262       typeWriters.addStuff(writer, type, symbolTable);
263       return typeWriters;
264    } // getGenerator
265

266    /**
267     * Return Wsdl2java's JavaDefinitionWriter object.
268     */

269    private Writers defWriters = new Writers();
270
271    public Generator getGenerator(Definition definition, SymbolTable symbolTable)
272    {
273       defWriters.addStuff(null, definition, symbolTable);
274       return defWriters;
275    } // getGenerator
276

277    // Hack class just to play with the idea of adding writers
278
protected class Writers implements Generator
279    {
280       Vector JavaDoc writers = new Vector JavaDoc();
281       SymbolTable symbolTable = null;
282       Generator baseWriter = null;
283
284       // entry or def, but not both, will be a parameter.
285
SymTabEntry entry = null;
286       Definition def = null;
287
288       public void addGenerator(Class JavaDoc writer)
289       {
290          writers.add(writer);
291       } // addWriter
292

293       public void addStuff(Generator baseWriter, SymTabEntry entry, SymbolTable symbolTable)
294       {
295          this.baseWriter = baseWriter;
296          this.entry = entry;
297          this.symbolTable = symbolTable;
298       } // addStuff
299

300       public void addStuff(Generator baseWriter, Definition def, SymbolTable symbolTable)
301       {
302          this.baseWriter = baseWriter;
303          this.def = def;
304          this.symbolTable = symbolTable;
305       } // addStuff
306

307       public void generate() throws IOException JavaDoc
308       {
309          if (baseWriter != null)
310          {
311             baseWriter.generate();
312          }
313          Class JavaDoc[] formalArgs = null;
314          Object JavaDoc[] actualArgs = null;
315          if (entry != null)
316          {
317             formalArgs = new Class JavaDoc[]{Emitter.class, entry.getClass(), SymbolTable.class};
318             actualArgs = new Object JavaDoc[]{emitter, entry, symbolTable};
319          }
320          else
321          {
322             formalArgs = new Class JavaDoc[]{Emitter.class, Definition.class, SymbolTable.class};
323             actualArgs = new Object JavaDoc[]{emitter, def, symbolTable};
324          }
325          for (int i = 0; i < writers.size(); ++i)
326          {
327             Class JavaDoc wClass = (Class JavaDoc)writers.get(i);
328             Generator gen = null;
329             try
330             {
331                Constructor JavaDoc ctor = wClass.getConstructor(formalArgs);
332                gen = (Generator)ctor.newInstance(actualArgs);
333             }
334             catch (Throwable JavaDoc t)
335             {
336                throw new IOException JavaDoc(Messages.getMessage("exception01", t.getMessage()));
337             }
338             gen.generate();
339          }
340       } // generate
341
} // class Writers
342

343    public void addGenerator(Class JavaDoc wsdlClass, Class JavaDoc generator)
344    {
345       // This is just a hack right now... it just works with Service
346
if (Message.class.isAssignableFrom(wsdlClass))
347       {
348          messageWriters.addGenerator(generator);
349       }
350       else if (PortType.class.isAssignableFrom(wsdlClass))
351       {
352          portTypeWriters.addGenerator(generator);
353       }
354       else if (Binding.class.isAssignableFrom(wsdlClass))
355       {
356          bindingWriters.addGenerator(generator);
357       }
358       else if (Service.class.isAssignableFrom(wsdlClass))
359       {
360          serviceWriters.addGenerator(generator);
361       }
362       else if (TypeEntry.class.isAssignableFrom(wsdlClass))
363       {
364          typeWriters.addGenerator(generator);
365       }
366       else if (Definition.class.isAssignableFrom(wsdlClass))
367       {
368          defWriters.addGenerator(generator);
369       }
370    } // addGenerator
371

372    /**
373     * Fill in the names of each SymTabEntry with the javaified name.
374     * Note: This method also ensures that anonymous types are
375     * given unique java type names.
376     */

377    protected void javifyNames(SymbolTable symbolTable)
378    {
379       int uniqueNum = 0;
380       HashMap JavaDoc anonQNames = new HashMap JavaDoc();
381       Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
382       while (it.hasNext())
383       {
384          Vector JavaDoc v = (Vector JavaDoc)it.next();
385          for (int i = 0; i < v.size(); ++i)
386          {
387             SymTabEntry entry = (SymTabEntry)v.elementAt(i);
388             if (entry.getName() != null)
389                continue;
390
391             // Use the type or the referenced type's QName to generate the java name.
392
if (entry instanceof TypeEntry)
393             {
394                TypeEntry tEntry = (TypeEntry)entry;
395                String JavaDoc dims = tEntry.getDimensions();
396                TypeEntry refType = tEntry.getRefType();
397                while (refType != null)
398                {
399                   tEntry = refType;
400                   dims += tEntry.getDimensions();
401                   refType = tEntry.getRefType();
402                }
403
404
405                // Need to javify the ref'd TypeEntry if it was not
406
// already processed
407
if (tEntry.getName() == null)
408                {
409                   // Get the QName of the ref'd TypeEntry, which
410
// is will be used to javify the name
411
QName JavaDoc typeQName = tEntry.getQName();
412                   if ((typeQName.getLocalPart().
413                           indexOf(SymbolTable.ANON_TOKEN) < 0))
414                   {
415                      // Normal Case: The ref'd type is not anonymous
416
// Simply construct the java name from
417
// the qName
418
tEntry.setName(emitter.getJavaName(typeQName));
419                   }
420                   else
421                   {
422                      // This is an anonymous type name.
423
// Axis uses '>' as a nesting token to generate
424
// unique qnames for anonymous types.
425
// Only consider the localName after the last '>'
426
// when generating the java name
427

428                             
429 // String localName = typeQName.getLocalPart();
430
// localName =
431
// localName.substring(
432
// localName.lastIndexOf(
433
// SymbolTable.ANON_TOKEN)+1);
434
// typeQName = new QName(typeQName.getNamespaceURI(),
435
// localName);
436

437                      String JavaDoc localName = typeQName.getLocalPart();
438
439                      // Check to see if this is an anonymous type,
440
// if it is, replace Axis' ANON_TOKEN with
441
// an underscore to make sure we don't run
442
// into name collisions with similarly named
443
// non-anonymous types
444
StringBuffer JavaDoc sb = new StringBuffer JavaDoc(localName);
445                      int aidx = -1;
446                      while (
447                              (aidx = sb.toString().indexOf(SymbolTable.ANON_TOKEN)) > -1)
448                      {
449                         sb.replace(aidx, aidx + SymbolTable.ANON_TOKEN.length(), "_");
450                      }
451                      localName = sb.toString();
452
453                      typeQName = new QName JavaDoc(typeQName.getNamespaceURI(),
454                              localName);
455
456                      // If there is already an existing type,
457
// there will be a collision.
458
// If there is an existing anon type,
459
// there will be a collision.
460
// In both cases, mangle the name.
461
symbolTable.getType(typeQName);
462                      if (anonQNames.get(typeQName) != null)
463                      {
464                         localName += "Type" + uniqueNum++;
465                         typeQName =
466                                 new QName JavaDoc(typeQName.getNamespaceURI(),
467                                         localName);
468                      }
469                      anonQNames.put(typeQName, typeQName);
470
471                      // Now set the name with the constructed qname
472
tEntry.setName(emitter.getJavaName(typeQName));
473                   }
474                }
475                // Set the entry with the same name as the ref'd entry
476
// but add the appropriate amount of dimensions
477
entry.setName(tEntry.getName() + dims);
478             }
479
480             // If it is not a type, then use this entry's QName to
481
// generate its name.
482
else
483             {
484                entry.setName(emitter.getJavaName(entry.getQName()));
485             }
486          }
487       }
488    } // javifyNames
489

490    /**
491     * setFaultContext:
492     * Processes the symbol table and sets the COMPLEX_TYPE_FAULT
493     * on each TypeEntry that is a complexType and is referenced in
494     * a fault message. TypeEntries that are the base or derived
495     * from such a TypeEntry are also marked with COMPLEX_TYPE_FAULT.
496     * The containing MessageEntry is marked with cOMPLEX_TYPE_FAULT, and
497     * all MessageEntries for faults are tagged with the
498     * EXCEPTION_CLASS_NAME variable, which indicates the java exception
499     * class name.
500     *
501     * @param symbolTable SymbolTable
502     */

503    private void setFaultContext(SymbolTable symbolTable)
504    {
505       Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
506       while (it.hasNext())
507       {
508          Vector JavaDoc v = (Vector JavaDoc)it.next();
509          for (int i = 0; i < v.size(); ++i)
510          {
511             SymTabEntry entry = (SymTabEntry)v.elementAt(i);
512             // Inspect each BindingEntry in the Symbol Table
513
if (entry instanceof BindingEntry)
514             {
515                BindingEntry bEntry = (BindingEntry)entry;
516                Map JavaDoc allOpFaults = bEntry.getFaults();
517                Iterator JavaDoc ops = allOpFaults.values().iterator();
518                // set the context for all faults for this binding.
519
while (ops.hasNext())
520                {
521                   ArrayList JavaDoc faults = (ArrayList JavaDoc)ops.next();
522                   for (int j = 0; j < faults.size(); ++j)
523                   {
524                      FaultInfo info = (FaultInfo)faults.get(j);
525                      setFaultContext(info, symbolTable);
526                   }
527                }
528             }
529          }
530       }
531    } // setFaultContext
532

533    /**
534     * setFaultContext:
535     * Helper routine for the setFaultContext method above.
536     * Examines the indicated fault and sets COMPLEX_TYPE_FAULT
537     * EXCEPTION_DATA_TYPE and EXCEPTION_CLASS_NAME as appropriate.
538     *
539     * @param fault FaultInfo to analyze
540     * @param symbolTable SymbolTable
541     */

542    private void setFaultContext(FaultInfo fault,
543                                 SymbolTable symbolTable)
544    {
545       QName JavaDoc faultXmlType = null;
546
547       Vector JavaDoc parts = new Vector JavaDoc();
548       // Get the parts of the fault's message.
549
// An IOException is thrown if the parts cannot be
550
// processed. Skip such parts for this analysis
551
try
552       {
553          symbolTable.getParametersFromParts(parts,
554                  fault.getMessage().getOrderedParts(null),
555                  false,
556                  fault.getName(),
557                  null);
558       }
559       catch (IOException JavaDoc e)
560       {
561       }
562
563       // Inspect each TypeEntry referenced in a Fault Message Part
564
String JavaDoc exceptionClassName = null;
565       for (int j = 0; j < parts.size(); j++)
566       {
567          TypeEntry te = ((Parameter)(parts.elementAt(j))).getType();
568
569          // If the TypeEntry is an element, advance to the type.
570
// This occurs if the message part uses the element= attribute
571
TypeEntry elementTE = null;
572          if (te instanceof Element)
573          {
574             elementTE = te;
575             te = te.getRefType();
576          }
577
578          // remember the QName of the type.
579
faultXmlType = te.getQName();
580
581          // Determine if the te should be processed using the
582
// simple type mapping or the complex type mapping
583
// NOTE: treat array types as simple types
584
if (te.getBaseType() != null ||
585                  te.isSimpleType() ||
586                  (te.getDimensions().length() > 0 &&
587                  te.getRefType().getBaseType() != null))
588          {
589             // Simple Type Exception
590
}
591          else
592          {
593             // Complex Type Exception
594
Boolean JavaDoc isComplexFault = (Boolean JavaDoc)te.getDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT);
595             if (isComplexFault == null ||
596                     !isComplexFault.booleanValue())
597             {
598                // Mark the type as a complex type fault
599
te.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
600                        new Boolean JavaDoc(true));
601                if (elementTE != null)
602                {
603                   te.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
604                           new Boolean JavaDoc(true));
605                }
606
607                // Mark all derived types as Complex Faults
608
HashSet JavaDoc derivedSet =
609                        org.jboss.axis.wsdl.symbolTable.Utils.getDerivedTypes(te, symbolTable);
610                Iterator JavaDoc derivedI = derivedSet.iterator();
611                while (derivedI.hasNext())
612                {
613                   TypeEntry derivedTE = (TypeEntry)
614                           derivedI.next();
615                   derivedTE.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
616                           new Boolean JavaDoc(true));
617                }
618                // Mark all base types as Complex Faults
619
TypeEntry base = SchemaUtils.getComplexElementExtensionBase(te.getNode(),
620                        symbolTable);
621                while (base != null)
622                {
623                   base.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
624                           new Boolean JavaDoc(true));
625                   base = SchemaUtils.getComplexElementExtensionBase(base.getNode(),
626                           symbolTable);
627                }
628             }
629             // The exception class name is the name of the type
630
exceptionClassName = te.getName();
631          }
632       }
633       // Set the name of the exception and
634
// whether the exception is a complex type
635
MessageEntry me = symbolTable.getMessageEntry(fault.getMessage().getQName());
636       if (me != null)
637       {
638          me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_DATA_TYPE,
639                  faultXmlType);
640          if (exceptionClassName != null)
641          {
642             me.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
643                     new Boolean JavaDoc(true));
644             me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME,
645                     exceptionClassName);
646          }
647          else
648          {
649             me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME,
650                     emitter.getJavaName(me.getQName()));
651          }
652
653       }
654    }
655
656    protected void determineInterfaceNames(SymbolTable symbolTable)
657    {
658       Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
659       while (it.hasNext())
660       {
661          Vector JavaDoc v = (Vector JavaDoc)it.next();
662          for (int i = 0; i < v.size(); ++i)
663          {
664             SymTabEntry entry = (SymTabEntry)v.elementAt(i);
665             if (entry instanceof BindingEntry)
666             {
667                // The SEI (Service Endpoint Interface) name
668
// is always the portType name.
669
BindingEntry bEntry = (BindingEntry)entry;
670                String JavaDoc seiName = null;
671
672                PortTypeEntry ptEntry = symbolTable.getPortTypeEntry(bEntry.getBinding().getPortType().getQName());
673                seiName = ptEntry.getName();
674                bEntry.setDynamicVar(JavaBindingWriter.INTERFACE_NAME, seiName);
675             }
676          }
677       }
678    } // determineInterfaceNames
679

680    /**
681     * Messages, PortTypes, Bindings, and Services can share the same name. If they do in this
682     * Definition, force their names to be suffixed with _PortType and _Service, respectively.
683     */

684    protected void resolveNameClashes(SymbolTable symbolTable)
685    {
686
687       // Keep a list of anonymous types so we don't try to resolve them twice.
688
HashSet JavaDoc anonTypes = new HashSet JavaDoc();
689
690       Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
691       while (it.hasNext())
692       {
693          Vector JavaDoc v = new Vector JavaDoc((Vector JavaDoc)it.next()); // New vector we can temporarily add to it
694

695          // Remove MessageEntries since they are not mapped
696
int index = 0;
697          while (index < v.size())
698          {
699             if (v.elementAt(index) instanceof MessageEntry)
700             {
701                v.removeElementAt(index);
702             }
703             else
704             {
705                index++;
706             }
707          }
708
709          if (v.size() > 1)
710          {
711             boolean resolve = true;
712             // Common Special Case:
713
// If a Type and Element have the same QName, and the Element
714
// references the Type, then they are the same class so
715
// don't bother mangling.
716
if (v.size() == 2 &&
717                     ((v.elementAt(0) instanceof Element &&
718                     v.elementAt(1) instanceof Type) ||
719                     (v.elementAt(1) instanceof Element &&
720                     v.elementAt(0) instanceof Type)))
721             {
722                Element e = null;
723                if (v.elementAt(0) instanceof Element)
724                {
725                   e = (Element)v.elementAt(0);
726                }
727                else
728                {
729                   e = (Element)v.elementAt(1);
730                }
731                BooleanHolder JavaDoc forElement = new BooleanHolder JavaDoc();
732                QName JavaDoc eType = Utils.getTypeQName(e.getNode(), forElement, false);
733                if (eType != null &&
734                        eType.equals(e.getQName()) &&
735                        !forElement.value)
736                   resolve = false;
737             }
738
739             // Other Special Case:
740
// If the names are already different, no mangling is needed.
741
if (resolve)
742             {
743                resolve = false; // Assume false
744
String JavaDoc name = null;
745                for (int i = 0; i < v.size() && !resolve; ++i)
746                {
747                   SymTabEntry entry = (SymTabEntry)v.elementAt(i);
748                   if (entry instanceof MessageEntry ||
749                           entry instanceof BindingEntry)
750                   {
751                      ; // Don't process these
752
}
753                   else if (name == null)
754                   {
755                      name = entry.getName();
756                   }
757                   else if (name.equals(entry.getName()))
758                   {
759                      resolve = true; // Need to do resolution
760
}
761
762                }
763             }
764
765             // Full Mangle if resolution is necessary.
766
if (resolve)
767             {
768                boolean firstType = true;
769                for (int i = 0; i < v.size(); ++i)
770                {
771                   SymTabEntry entry = (SymTabEntry)v.elementAt(i);
772                   if (entry instanceof Element)
773                   {
774                      entry.setName(mangleName(entry.getName(),
775                              "_ElemType"));
776
777                      // If this global element was defined using
778
// an anonymous type, then need to change the
779
// java name of the anonymous type to match.
780
QName JavaDoc anonQName = new QName JavaDoc(entry.getQName().getNamespaceURI(),
781                              SymbolTable.ANON_TOKEN +
782                              entry.getQName().getLocalPart());
783                      TypeEntry anonType = symbolTable.getType(anonQName);
784                      if (anonType != null)
785                      {
786                         anonType.setName(entry.getName());
787                         anonTypes.add(anonType);
788                      }
789                   }
790                   else if (entry instanceof TypeEntry)
791                   {
792                      // Search all other types for java names that match this one.
793
// The sameJavaClass method returns true if the java names are
794
// the same (ignores [] ).
795
if (firstType)
796                      {
797                         firstType = false;
798                         Iterator JavaDoc types = symbolTable.getTypeIndex().values().iterator();
799                         while (types.hasNext())
800                         {
801                            TypeEntry type = (TypeEntry)
802                                    types.next();
803                            if (type != entry && type.getBaseType() == null &&
804                                    sameJavaClass(entry.getName(), type.getName()))
805                            {
806                               v.add(type);
807                            }
808                         }
809                      }
810                      // If this is an anonymous type, it's name was resolved in
811
// the previous if block. Don't reresolve it.
812
if (!anonTypes.contains(entry))
813                      {
814                         entry.setName(mangleName(entry.getName(), "_Type"));
815                      }
816                   }
817                   else if (entry instanceof PortTypeEntry)
818                   {
819                      entry.setName(mangleName(entry.getName(), "_Port"));
820                   }
821                   else if (entry instanceof ServiceEntry)
822                   {
823                      entry.setName(mangleName(entry.getName(),
824                              "_Service"));
825                   }
826                   // else if (entry instanceof MessageEntry) {
827
// we don't care about messages
828
// }
829
else if (entry instanceof BindingEntry)
830                   {
831                      BindingEntry bEntry = (BindingEntry)entry;
832
833                      // If there is no literal use, then we never see a
834
// class named directly from the binding name. They
835
// all have suffixes: Stub, Skeleton, Impl.
836
// If there IS literal use, then the SDI will be
837
// named after the binding name, so there is the
838
// possibility of a name clash.
839
if (bEntry.hasLiteral())
840                      {
841                         entry.setName(mangleName(entry.getName(),
842                                 "_Binding"));
843                      }
844                   }
845                }
846             }
847          }
848       }
849    } // resolveNameClashes
850

851    /**
852     * Change the indicated type name into a mangled form using the mangle string.
853     */

854    private String JavaDoc mangleName(String JavaDoc name, String JavaDoc mangle)
855    {
856       int index = name.indexOf("[");
857       if (index >= 0)
858       {
859          String JavaDoc pre = name.substring(0, index);
860          String JavaDoc post = name.substring(index);
861          return pre + mangle + post;
862       }
863       else
864          return name + mangle;
865    }
866
867    /**
868     * Returns true if same java class, ignore []
869     */

870    private boolean sameJavaClass(String JavaDoc one, String JavaDoc two)
871    {
872       int index1 = one.indexOf("[");
873       int index2 = two.indexOf("[");
874       if (index1 > 0)
875          one = one.substring(0, index1);
876       if (index2 > 0)
877          two = two.substring(0, index2);
878       return one.equals(two);
879    }
880
881    /**
882     * The --all flag is set on the command line (or generateAll(true) is called
883     * on WSDL2Java). Set all symbols as referenced (except nonSOAP bindings
884     * which we don't know how to deal with).
885     */

886    protected void setAllReferencesToTrue()
887    {
888       Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
889       while (it.hasNext())
890       {
891          Vector JavaDoc v = (Vector JavaDoc)it.next();
892          for (int i = 0; i < v.size(); ++i)
893          {
894             SymTabEntry entry = (SymTabEntry)v.elementAt(i);
895             if (entry instanceof BindingEntry &&
896                     ((BindingEntry)entry).getBindingType() !=
897                     BindingEntry.TYPE_SOAP)
898             {
899                entry.setIsReferenced(false);
900             }
901             else
902             {
903                entry.setIsReferenced(true);
904             }
905          }
906       }
907    } // setAllReferencesToTrue
908

909    /**
910     * If a binding's type is not TYPE_SOAP, then we don't use that binding
911     * or that binding's portType.
912     */

913    protected void ignoreNonSOAPBindings(SymbolTable symbolTable)
914    {
915
916       // Look at all uses of the portTypes. If none of the portType's bindings are of type
917
// TYPE_SOAP, then turn off that portType's isReferenced flag.
918

919       Vector JavaDoc unusedPortTypes = new Vector JavaDoc();
920       Vector JavaDoc usedPortTypes = new Vector JavaDoc();
921
922       Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
923       while (it.hasNext())
924       {
925          Vector JavaDoc v = (Vector JavaDoc)it.next();
926          for (int i = 0; i < v.size(); ++i)
927          {
928             SymTabEntry entry = (SymTabEntry)v.elementAt(i);
929             if (entry instanceof BindingEntry)
930             {
931                BindingEntry bEntry = (BindingEntry)entry;
932                Binding binding = bEntry.getBinding();
933                PortType portType = binding.getPortType();
934                PortTypeEntry ptEntry =
935                        symbolTable.getPortTypeEntry(portType.getQName());
936
937                if (bEntry.getBindingType() == BindingEntry.TYPE_SOAP)
938                {
939                   // If a binding is of type TYPE_SOAP, then mark its portType used
940
// (ie., add it to the usedPortTypes list. If the portType was
941
// previously marked as unused, unmark it (in other words, remove it
942
// from the unusedPortTypes list).
943
usedPortTypes.add(ptEntry);
944                   if (unusedPortTypes.contains(ptEntry))
945                   {
946                      unusedPortTypes.remove(ptEntry);
947                   }
948                }
949                else
950                {
951                   bEntry.setIsReferenced(false);
952
953                   // If a binding is not of type TYPE_SOAP, then mark its portType as
954
// unused ONLY if it hasn't already been marked as used.
955
if (!usedPortTypes.contains(ptEntry))
956                   {
957                      unusedPortTypes.add(ptEntry);
958                   }
959                }
960             }
961          }
962       }
963
964       // Go through all the portTypes that are marked as unused and set their isReferenced flags
965
// to false.
966
for (int i = 0; i < unusedPortTypes.size(); ++i)
967       {
968          PortTypeEntry ptEntry = (PortTypeEntry)unusedPortTypes.get(i);
969          ptEntry.setIsReferenced(false);
970       }
971    } // ignoreNonSOAPBindings
972

973    protected void constructSignatures(SymbolTable symbolTable)
974    {
975       Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
976       while (it.hasNext())
977       {
978          Vector JavaDoc v = (Vector JavaDoc)it.next();
979          for (int i = 0; i < v.size(); ++i)
980          {
981             SymTabEntry entry = (SymTabEntry)v.elementAt(i);
982             if (entry instanceof BindingEntry)
983             {
984                BindingEntry bEntry = (BindingEntry)entry;
985                Binding binding = bEntry.getBinding();
986                PortTypeEntry ptEntry =
987                        symbolTable.getPortTypeEntry(binding.getPortType().getQName());
988                PortType portType = ptEntry.getPortType();
989                Iterator JavaDoc operations = portType.getOperations().iterator();
990                while (operations.hasNext())
991                {
992                   Operation operation = (Operation)operations.next();
993                   OperationType type = operation.getStyle();
994                   String JavaDoc name = operation.getName();
995                   Parameters parameters = bEntry.getParameters(operation);
996                   if (type == OperationType.SOLICIT_RESPONSE)
997                   {
998                      parameters.signature = " // " + Messages.getMessage("invalidSolResp00", name);
999                      System.err.println(Messages.getMessage("invalidSolResp00", name));
1000                  }
1001                  else if (type == OperationType.NOTIFICATION)
1002                  {
1003                     parameters.signature = " // " + Messages.getMessage("invalidNotif00", name);
1004                     System.err.println(Messages.getMessage("invalidNotif00", name));
1005                  }
1006                  else
1007                  { // ONE_WAY or REQUEST_RESPONSE
1008
if (parameters != null)
1009                     {
1010                        parameters.signature = constructSignature(parameters, name);
1011                     }
1012                  }
1013               }
1014            }
1015         }
1016      }
1017   } // constructSignatures
1018

1019   /**
1020    * Construct the signature, which is used by both the interface and the stub.
1021    */

1022   private String JavaDoc constructSignature(Parameters parms, String JavaDoc opName)
1023   {
1024      String JavaDoc name = Utils.xmlNameToJava(opName);
1025
1026      String JavaDoc ret = "void";
1027      if (parms != null && parms.returnParam != null)
1028      {
1029         ret = Utils.getParameterTypeName(parms.returnParam);
1030      }
1031      String JavaDoc signature = " public " + ret + " " + name + "(";
1032
1033      boolean needComma = false;
1034
1035      for (int i = 0; parms != null && i < parms.list.size(); ++i)
1036      {
1037         Parameter p = (Parameter)parms.list.get(i);
1038
1039         if (needComma)
1040         {
1041            signature = signature + ", ";
1042         }
1043         else
1044         {
1045            needComma = true;
1046         }
1047
1048         String JavaDoc javifiedName = Utils.xmlNameToJava(p.getName());
1049         if (p.getMode() == Parameter.IN)
1050         {
1051            signature = signature + Utils.getParameterTypeName(p) + " " + javifiedName;
1052         }
1053         else
1054         {
1055            signature = signature + Utils.holder(p.getMIMEInfo(), p.getType(), emitter) + " "
1056                    + javifiedName;
1057         }
1058      }
1059      signature = signature + ") throws java.rmi.RemoteException";
1060      if (parms != null && parms.faults != null)
1061      {
1062         // Collect the list of faults into a single string, separated by commas.
1063

1064         Iterator JavaDoc i = parms.faults.values().iterator();
1065         while (i.hasNext())
1066         {
1067            Fault fault = (Fault)i.next();
1068            String JavaDoc exceptionName =
1069                    Utils.getFullExceptionName(fault.getMessage(), symbolTable);
1070            if (exceptionName != null)
1071            {
1072               signature = signature + ", " + exceptionName;
1073            }
1074         }
1075      }
1076      return signature;
1077   } // constructSignature
1078

1079   /**
1080    * Find all inout/out parameters and add a flag to the Type of that parameter saying a holder
1081    * is needed.
1082    */

1083   protected void determineIfHoldersNeeded(SymbolTable symbolTable)
1084   {
1085      Iterator JavaDoc it = symbolTable.getHashMap().values().iterator();
1086      while (it.hasNext())
1087      {
1088         Vector JavaDoc v = (Vector JavaDoc)it.next();
1089         for (int i = 0; i < v.size(); ++i)
1090         {
1091            if (v.get(i) instanceof BindingEntry)
1092            {
1093               // If entry is a BindingEntry, look at all the Parameters
1094
// in its portType
1095
BindingEntry bEntry = (BindingEntry)v.get(i);
1096// PortTypeEntry ptEntry =
1097
// symbolTable.getPortTypeEntry(bEntry.getBinding().getPortType().getQName());
1098
Iterator JavaDoc operations =
1099                       bEntry.getParameters().values().iterator();
1100               while (operations.hasNext())
1101               {
1102                  Parameters parms = (Parameters)operations.next();
1103                  for (int j = 0; j < parms.list.size(); ++j)
1104                  {
1105                     Parameter p =
1106                             (Parameter)parms.list.get(j);
1107
1108                     // If the given parameter is an inout or out parameter, then
1109
// set a HOLDER_IS_NEEDED flag using the dynamicVar design.
1110
if (p.getMode() != Parameter.IN)
1111                     {
1112                        TypeEntry typeEntry = p.getType();
1113                        typeEntry.setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
1114                                new Boolean JavaDoc(true));
1115                        //If this is a complex then set the HOLDER_IS_NEEDED
1116
//for the reftype too.
1117
if (!typeEntry.isSimpleType() && typeEntry.getRefType() != null)
1118                        {
1119                           typeEntry.getRefType().setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
1120                                   new Boolean JavaDoc(true));
1121                        }
1122
1123                        // If the type is a DefinedElement, need to
1124
// set HOLDER_IS_NEEDED on the anonymous type.
1125
QName JavaDoc anonQName = SchemaUtils.
1126                                getElementAnonQName(p.getType().getNode());
1127                        if (anonQName != null)
1128                        {
1129                           TypeEntry anonType =
1130                                   symbolTable.getType(anonQName);
1131                           if (anonType != null)
1132                           {
1133                              anonType.setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
1134                                      new Boolean JavaDoc(true));
1135                           }
1136                        }
1137                     }
1138                  }
1139               }
1140            }
1141         }
1142      }
1143   } // determineIfHoldersNeeded
1144

1145   /**
1146    * Get TypeMapping to use for translating
1147    * QNames to java base types
1148    */

1149   BaseTypeMapping btm = null;
1150
1151   public void setBaseTypeMapping(BaseTypeMapping btm)
1152   {
1153      this.btm = btm;
1154   }
1155
1156   public BaseTypeMapping getBaseTypeMapping()
1157   {
1158      if (btm == null)
1159      {
1160         btm = new BaseTypeMapping()
1161         {
1162            TypeMapping defaultTM = DefaultTypeMappingImpl.getSingleton();
1163
1164            public String JavaDoc getBaseName(QName JavaDoc qNameIn)
1165            {
1166               javax.xml.namespace.QName JavaDoc qName =
1167                       new javax.xml.namespace.QName JavaDoc(qNameIn.getNamespaceURI(),
1168                               qNameIn.getLocalPart());
1169               Class JavaDoc cls = defaultTM.getClassForQName(qName);
1170               if (cls == null)
1171                  return null;
1172               else
1173                  return JavaUtils.getTextClassName(cls.getName());
1174            }
1175         };
1176      }
1177      return btm;
1178   }
1179
1180} // class JavaGeneratorFactory
1181
Popular Tags