View Javadoc

1   /*
2    * Copyright 2001-2004 The Apache Software Foundation.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  
17  package org.apache.geronimo.ews.jaxrpcmapping;
18  
19  /***
20   * @author Ias (iasandcb@tmax.co.kr)
21   *
22   */
23  
24  import java.io.IOException;
25  import java.lang.reflect.Constructor;
26  import java.util.ArrayList;
27  import java.util.HashMap;
28  import java.util.HashSet;
29  import java.util.Iterator;
30  import java.util.Map;
31  import java.util.Vector;
32  
33  import javax.wsdl.Binding;
34  import javax.wsdl.Definition;
35  import javax.wsdl.Fault;
36  import javax.wsdl.Message;
37  import javax.wsdl.Operation;
38  import javax.wsdl.OperationType;
39  import javax.wsdl.Port;
40  import javax.wsdl.PortType;
41  import javax.wsdl.Service;
42  import javax.xml.namespace.QName;
43  import javax.xml.rpc.holders.BooleanHolder;
44  
45  import org.apache.axis.utils.JavaUtils;
46  import org.apache.axis.utils.Messages;
47  import org.apache.axis.wsdl.gen.Generator;
48  import org.apache.axis.wsdl.gen.GeneratorFactory;
49  import org.apache.axis.wsdl.gen.NoopGenerator;
50  import org.apache.axis.wsdl.symbolTable.BaseTypeMapping;
51  import org.apache.axis.wsdl.symbolTable.BindingEntry;
52  import org.apache.axis.wsdl.symbolTable.ContainedAttribute;
53  import org.apache.axis.wsdl.symbolTable.Element;
54  import org.apache.axis.wsdl.symbolTable.ElementDecl;
55  import org.apache.axis.wsdl.symbolTable.FaultInfo;
56  import org.apache.axis.wsdl.symbolTable.MessageEntry;
57  import org.apache.axis.wsdl.symbolTable.Parameter;
58  import org.apache.axis.wsdl.symbolTable.Parameters;
59  import org.apache.axis.wsdl.symbolTable.PortTypeEntry;
60  import org.apache.axis.wsdl.symbolTable.SchemaUtils;
61  import org.apache.axis.wsdl.symbolTable.ServiceEntry;
62  import org.apache.axis.wsdl.symbolTable.SymTabEntry;
63  import org.apache.axis.wsdl.symbolTable.SymbolTable;
64  import org.apache.axis.wsdl.symbolTable.Type;
65  import org.apache.axis.wsdl.symbolTable.TypeEntry;
66  import org.apache.axis.wsdl.toJava.Emitter;
67  import org.apache.axis.wsdl.toJava.JavaBindingWriter;
68  import org.apache.axis.wsdl.toJava.JavaDefinitionWriter;
69  import org.apache.axis.wsdl.toJava.JavaDeployWriter;
70  import org.apache.axis.wsdl.toJava.JavaGeneratorFactory;
71  import org.apache.axis.wsdl.toJava.JavaServiceWriter;
72  import org.apache.axis.wsdl.toJava.JavaTypeWriter;
73  import org.apache.axis.wsdl.toJava.JavaUndeployWriter;
74  import org.apache.axis.wsdl.toJava.Utils;
75  
76  /***
77   * This is WsdlToJ2ee's implementation of the GeneratorFactory
78   *
79   * @author Ias (iasandcb@tmax.co.kr)
80   */
81  
82  public class J2eeGeneratorFactory implements GeneratorFactory {
83      protected J2eeEmitter emitter;
84      protected SymbolTable symbolTable;
85  
86      private JaxRpcMapper mapper;
87  
88      /***
89       * Default constructor.  Note that this class is unusable until setEmitter
90       * is called.
91       */
92      public J2eeGeneratorFactory() {
93          addGenerators();
94      } // ctor
95  
96      public J2eeGeneratorFactory(J2eeEmitter emitter) {
97          this.emitter = emitter;
98          addGenerators();
99      } // ctor
100 
101     public void setEmitter(J2eeEmitter emitter) {
102         this.emitter = emitter;
103     } // setEmitter
104 
105     private void addGenerators() {
106         addMessageGenerators();
107         addPortTypeGenerators();
108         addBindingGenerators();
109         addServiceGenerators();
110         addTypeGenerators();
111         addDefinitionGenerators();
112     } // addGenerators
113 
114     /***
115      * These addXXXGenerators are called by the constructor.
116      * If an extender of this factory wants to CHANGE the set
117      * of generators that are called per WSDL construct, they
118      * should override these addXXXGenerators methods.  If all
119      * an extender wants to do is ADD a generator, then the
120      * extension should simply call addGenerator.
121      * (NOTE:  It doesn't quite work this way, yet.  Only the
122      * Definition generators fit this model at this point in
123      * time.)
124      */
125     protected void addMessageGenerators() {
126     } // addMessageGenerators
127 
128     protected void addPortTypeGenerators() {
129     } // addPortTypeGenerators
130 
131     protected void addBindingGenerators() {
132     } // addBindingGenerators
133 
134     protected void addServiceGenerators() {
135     } // addServiceGenerators
136 
137     protected void addTypeGenerators() {
138     } // addTypeGenerators
139 
140     protected void addDefinitionGenerators() {
141         addGenerator(Definition.class, JavaDefinitionWriter.class); // for faults
142         addGenerator(Definition.class, JavaDeployWriter.class); // for deploy.wsdd
143         addGenerator(Definition.class, JavaUndeployWriter.class); // for undeploy.wsdd
144     } // addDefinitionGenerators
145 
146     /***
147      * Do the Wsdl2java generator pass:
148      * - resolve name clashes
149      * - construct signatures
150      */
151     public void generatorPass(Definition def, SymbolTable symbolTable) {
152         mapper = emitter.getJaxRpcMapper();
153         this.symbolTable = symbolTable;
154         javifyNames(symbolTable);
155         setFaultContext(symbolTable);
156         resolveNameClashes(symbolTable);
157         determineInterfaceNames(symbolTable);
158         if (emitter.isAllWanted()) {
159             setAllReferencesToTrue();
160         } else {
161             ignoreNonSOAPBindings(symbolTable);
162         }
163         constructSignatures(symbolTable);
164         determineIfHoldersNeeded(symbolTable);
165     } // generatorPass
166 
167     /***
168      * Since Wsdl2java doesn't emit anything for Messages, return the No-op generator.
169      */
170     private Writers messageWriters = new Writers();
171 
172     public Generator getGenerator(Message message, SymbolTable symbolTable) {
173         MessageEntry mEntry = symbolTable.getMessageEntry(message.getQName());
174         messageWriters.addStuff(new NoopGenerator(), mEntry, symbolTable);
175         return messageWriters;
176     } // getGenerator
177 
178     /***
179      * Return Wsdl2java's JavaPortTypeWriter object.
180      */
181     private Writers portTypeWriters = new Writers();
182 
183     public Generator getGenerator(PortType portType, SymbolTable symbolTable) {
184         PortTypeEntry ptEntry = symbolTable.getPortTypeEntry(portType.getQName());
185         portTypeWriters.addStuff(new NoopGenerator(), ptEntry, symbolTable);
186         return portTypeWriters;
187     } // getGenerator
188 
189     /***
190      * Return Wsdl2java's JavaBindingWriter object.
191      */
192     protected Writers bindingWriters = new Writers();
193 
194     public Generator getGenerator(Binding binding, SymbolTable symbolTable) {
195         Generator writer = new J2eeBindingWriter(emitter, binding, symbolTable);
196         BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
197         bindingWriters.addStuff(writer, bEntry, symbolTable);
198         return bindingWriters;
199     } // getGenerator
200 
201     /***
202      * Return Wsdl2java's JavaServiceWriter object.
203      */
204     protected Writers serviceWriters = new Writers();
205 
206     public Generator getGenerator(Service service, SymbolTable symbolTable) {
207         Generator writer = new JavaServiceWriter(emitter, service, symbolTable);
208         ServiceEntry sEntry = symbolTable.getServiceEntry(service.getQName());
209         serviceWriters.addStuff(writer, sEntry, symbolTable);
210         return serviceWriters;
211     } // getGenerator
212 
213     /***
214      * Return Wsdl2java's JavaTypeWriter object.
215      */
216     protected Writers typeWriters = new Writers();
217 
218     public Generator getGenerator(TypeEntry type, SymbolTable symbolTable) {
219         Generator writer = new JavaTypeWriter(emitter, type, symbolTable);
220         typeWriters.addStuff(writer, type, symbolTable);
221         return typeWriters;
222     } // getGenerator
223 
224     /***
225      * Return Wsdl2java's JavaDefinitionWriter object.
226      */
227     private Writers defWriters = new Writers();
228 
229     public Generator getGenerator(Definition definition, SymbolTable symbolTable) {
230         defWriters.addStuff(null, definition, symbolTable);
231         return defWriters;
232     } // getGenerator
233 
234     // Hack class just to play with the idea of adding writers
235     protected class Writers implements Generator {
236         Vector writers = new Vector();
237         SymbolTable symbolTable = null;
238         Generator baseWriter = null;
239 
240         // entry or def, but not both, will be a parameter.
241         SymTabEntry entry = null;
242         Definition def = null;
243 
244         public void addGenerator(Class writer) {
245             writers.add(writer);
246         } // addWriter
247 
248         public void addStuff(Generator baseWriter, SymTabEntry entry, SymbolTable symbolTable) {
249             this.baseWriter = baseWriter;
250             this.entry = entry;
251             this.symbolTable = symbolTable;
252         } // addStuff
253 
254         public void addStuff(Generator baseWriter, Definition def, SymbolTable symbolTable) {
255             this.baseWriter = baseWriter;
256             this.def = def;
257             this.symbolTable = symbolTable;
258         } // addStuff
259 
260         public void generate() throws IOException {
261             if (baseWriter != null) {
262                 baseWriter.generate();
263             }
264             Class[] formalArgs = null;
265             Object[] actualArgs = null;
266             if (entry != null) {
267                 formalArgs = new Class[]{Emitter.class, entry.getClass(), SymbolTable.class};
268                 actualArgs = new Object[]{emitter, entry, symbolTable};
269             } else {
270                 formalArgs = new Class[]{Emitter.class, Definition.class, SymbolTable.class};
271                 actualArgs = new Object[]{emitter, def, symbolTable};
272             }
273             for (int i = 0; i < writers.size(); ++i) {
274                 Class wClass = (Class) writers.get(i);
275                 Generator gen = null;
276                 try {
277                     Constructor ctor = wClass.getConstructor(formalArgs);
278                     gen = (Generator) ctor.newInstance(actualArgs);
279                 } catch (Throwable t) {
280                     throw new IOException(Messages.getMessage("exception01", t.getMessage()));
281                 }
282                 gen.generate();
283             }
284         } // generate
285     } // class Writers
286 
287     public void addGenerator(Class wsdlClass, Class generator) {
288         // This is just a hack right now... it just works with Service
289         if (Message.class.isAssignableFrom(wsdlClass)) {
290             messageWriters.addGenerator(generator);
291         } else if (PortType.class.isAssignableFrom(wsdlClass)) {
292             portTypeWriters.addGenerator(generator);
293         } else if (Binding.class.isAssignableFrom(wsdlClass)) {
294             bindingWriters.addGenerator(generator);
295         } else if (Service.class.isAssignableFrom(wsdlClass)) {
296             serviceWriters.addGenerator(generator);
297         } else if (TypeEntry.class.isAssignableFrom(wsdlClass)) {
298             typeWriters.addGenerator(generator);
299         } else if (Definition.class.isAssignableFrom(wsdlClass)) {
300             defWriters.addGenerator(generator);
301         }
302     } // addGenerator
303 
304     /***
305      * Fill in the names of each SymTabEntry with the javaified name.
306      * Note: This method also ensures that anonymous types are
307      * given unique java type names.
308      */
309     protected void javifyNames(SymbolTable symbolTable) {
310         int uniqueNum = 0;
311         HashMap anonQNames = new HashMap();
312         Iterator it = symbolTable.getHashMap().values().iterator();
313         while (it.hasNext()) {
314             Vector v = (Vector) it.next();
315             for (int i = 0; i < v.size(); ++i) {
316                 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
317                 if (entry.getName() != null)
318                     continue;
319 
320                 // Use the type or the referenced type's QName to generate the java name.
321                 if (entry instanceof TypeEntry) {
322                     uniqueNum = javifyTypeEntryName(symbolTable, (TypeEntry) entry, anonQNames, uniqueNum);
323                 }
324                 // If it is not a type, then use this entry's QName to
325                 // generate its name.
326                 else {
327                     entry.setName(emitter.getJavaName(entry.getQName()));
328                 }
329             }
330         }
331     } // javifyNames
332 
333     /***
334      * Refactored to call recursively for JAX-RPC 1.1 spec 4.2.5.
335      */
336     protected int javifyTypeEntryName(SymbolTable symbolTable, TypeEntry entry, HashMap anonQNames, int uniqueNum) {
337         TypeEntry tEntry = entry;
338         String dims = tEntry.getDimensions();
339         TypeEntry refType = tEntry.getRefType();
340         while (refType != null) {
341             tEntry = refType;
342             dims += tEntry.getDimensions();
343             refType = tEntry.getRefType();
344         }
345         TypeEntry te = tEntry;
346         while (te != null) {
347             TypeEntry base = SchemaUtils.getBaseType(te, symbolTable);
348             if (base == null)
349                 break;
350             uniqueNum = javifyTypeEntryName(symbolTable, base, anonQNames, uniqueNum);
351             if (Utils.getEnumerationBaseAndValues(te.getNode(), symbolTable) == null
352                     && SchemaUtils.getContainedAttributeTypes(te.getNode(), symbolTable) == null) {
353                 if (base.isSimpleType()) {
354                     // Case 1:
355                     // <simpleType name="mySimpleStringType">
356                     //   <restriction base="xs:string">
357                     //   </restriction>
358                     // </simpleType>
359                     te.setSimpleType(true);
360                     te.setName(base.getName());
361                     te.setRefType(base);
362                 }
363                 if (base.isBaseType()) {
364                     // Case 2:
365                     // <simpleType name="FooString">
366                     //   <restriction base="foo:mySimpleStringType">
367                     //   </restriction>
368                     // </simpleType>
369                     te.setBaseType(true);
370                     te.setName(base.getName());
371                     te.setRefType(base);
372                 }
373             }
374             if (!te.isSimpleType())
375                 break;
376             te = base;
377         }
378 
379         // Need to javify the ref'd TypeEntry if it was not
380         // already processed
381         if (tEntry.getName() == null) {
382             // Get the QName of the ref'd TypeEntry, which
383             // is will be used to javify the name
384             QName typeQName = tEntry.getQName();
385 
386             // In case of <xsd:list itemType="...">,
387             // set typeQName to the value of the itemType attribute.
388             QName itemType = SchemaUtils.getListItemType(tEntry.getNode());
389             boolean isArray = false;
390             if (itemType != null) {
391                 typeQName = itemType;
392                 // OW Guillaume Change
393                 // found a list
394                 isArray = true;
395             }
396             if (typeQName.getLocalPart().
397                     indexOf(SymbolTable.ANON_TOKEN) >= 0) {
398                 // This is an anonymous type name.
399                 // Axis uses '>' as a nesting token to generate
400                 // unique qnames for anonymous types.
401                 // Only consider the localName after the last '>'
402                 // when generating the java name
403 
404                 String localName = typeQName.getLocalPart();
405 
406                 // If there is already an existing type,
407                 // there will be a collision.
408                 // If there is an existing anon type,
409                 // there will be a  collision.
410                 // In both cases, mangle the name.
411                 symbolTable.getType(typeQName);
412                 if (anonQNames.get(typeQName) != null) {
413                     localName += "Type" + uniqueNum++;
414                     typeQName =
415                             new QName(typeQName.getNamespaceURI(),
416                                     localName);
417                 }
418                 anonQNames.put(typeQName, typeQName);
419             }
420             // Now set the name with the constructed qname
421             String javaType = mapper.getJavaType(typeQName);
422             if (javaType == null) {
423                 javaType = emitter.getJavaName(typeQName);
424             }
425             if (isArray) {
426                 javaType += "[]";
427             }
428             tEntry.setName(javaType);
429 
430             Vector elements = tEntry.getContainedElements();
431             if (elements != null) {
432                 for (int i = 0; i < elements.size(); i++) {
433                     ElementDecl elem = (ElementDecl) elements.get(i);
434                     String varName = emitter.getJavaVariableName(typeQName, elem.getQName(), true);
435                     elem.setName(varName);
436                 }
437             }
438             Vector attributes = tEntry.getContainedAttributes();
439             if (attributes != null) {
440                 for (int i = 0; i < attributes.size(); i++) {
441                     ContainedAttribute attr = (ContainedAttribute) attributes.get(i);
442                     String varName = emitter.getJavaVariableName(typeQName, attr.getQName(), false);
443                     attr.setName(varName);
444                 }
445             }
446         }
447         // Set the entry with the same name as the ref'd entry
448         // but add the appropriate amount of dimensions
449         entry.setName(tEntry.getName() + dims);
450         return uniqueNum;
451     }
452 
453     /***
454      * setFaultContext:
455      * Processes the symbol table and sets the COMPLEX_TYPE_FAULT
456      * on each TypeEntry that is a complexType and is referenced in
457      * a fault message.  TypeEntries that are the base or derived
458      * from such a TypeEntry are also marked with COMPLEX_TYPE_FAULT.
459      * The containing MessageEntry is marked with cOMPLEX_TYPE_FAULT, and
460      * all MessageEntries for faults are tagged with the
461      * EXCEPTION_CLASS_NAME variable, which indicates the java exception
462      * class name.
463      *
464      * @param symbolTable SymbolTable
465      */
466     private void setFaultContext(SymbolTable symbolTable) {
467         Iterator it = symbolTable.getHashMap().values().iterator();
468         while (it.hasNext()) {
469             Vector v = (Vector) it.next();
470             for (int i = 0; i < v.size(); ++i) {
471                 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
472                 // Inspect each BindingEntry in the Symbol Table
473                 if (entry instanceof BindingEntry) {
474                     BindingEntry bEntry = (BindingEntry) entry;
475                     HashMap allOpFaults = bEntry.getFaults();
476                     Iterator ops = allOpFaults.values().iterator();
477                     // set the context for all faults for this binding.
478                     while (ops.hasNext()) {
479                         ArrayList faults = (ArrayList) ops.next();
480                         for (int j = 0; j < faults.size(); ++j) {
481                             FaultInfo info = (FaultInfo) faults.get(j);
482                             setFaultContext(info, symbolTable);
483                         }
484                     }
485                 }
486             }
487         }
488     } // setFaultContext
489 
490     /***
491      * setFaultContext:
492      * Helper routine for the setFaultContext method above.
493      * Examines the indicated fault and sets COMPLEX_TYPE_FAULT
494      * EXCEPTION_DATA_TYPE and EXCEPTION_CLASS_NAME as appropriate.
495      *
496      * @param fault       FaultInfo to analyze
497      * @param symbolTable SymbolTable
498      */
499     private void setFaultContext(FaultInfo fault,
500                                  SymbolTable symbolTable) {
501         QName faultXmlType = null;
502         Vector parts = new Vector();
503         // Get the parts of the fault's message.
504         // An IOException is thrown if the parts cannot be
505         // processed.  Skip such parts for this analysis
506         try {
507             symbolTable.getParametersFromParts(parts,
508                     fault.getMessage().getOrderedParts(null),
509                     false,
510                     fault.getName(),
511                     null);
512         } catch (IOException e) {
513         }
514 
515         // Inspect each TypeEntry referenced in a Fault Message Part
516         String exceptionClassName = null;
517         QName faultMessageQName = fault.getMessage().getQName();
518         for (int j = 0; j < parts.size(); j++) {
519             TypeEntry te = ((Parameter) (parts.elementAt(j))).getType();
520 
521             // If the TypeEntry is an element, advance to the type.
522             // This occurs if the message part uses the element= attribute
523             TypeEntry elementTE = null;
524             if (te instanceof Element) {
525                 elementTE = te;
526                 te = te.getRefType();
527             }
528 
529             // remember the QName of the type.
530             faultXmlType = te.getQName();
531 
532             // Determine if the te should be processed using the
533             // simple type mapping or the complex type mapping
534             // NOTE: treat array types as simple types
535             if (te.getBaseType() != null ||
536                     te.isSimpleType() ||
537                     (te.getDimensions().length() > 0 &&
538                     te.getRefType().getBaseType() != null)) {
539                 // Simple Type Exception
540             } else {
541                 // Complex Type Exception
542                 Boolean isComplexFault = (Boolean) te.getDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT);
543                 if (isComplexFault == null ||
544                         !isComplexFault.booleanValue()) {
545                     // Mark the type as a complex type fault
546                     te.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
547                             Boolean.TRUE);
548                     if (elementTE != null) {
549                         te.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
550                                 Boolean.TRUE);
551                     }
552 
553                     // Mark all derived types as Complex Faults
554                     HashSet derivedSet =
555                             org.apache.axis.wsdl.symbolTable.Utils.getDerivedTypes(te, symbolTable);
556                     Iterator derivedI = derivedSet.iterator();
557                     while (derivedI.hasNext()) {
558                         TypeEntry derivedTE = (TypeEntry)
559                                 derivedI.next();
560                         derivedTE.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
561                                 Boolean.TRUE);
562                     }
563                     // Mark all base types as Complex Faults
564                     TypeEntry base = SchemaUtils.getComplexElementExtensionBase(te.getNode(),
565                             symbolTable);
566                     while (base != null) {
567                         base.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
568                                 Boolean.TRUE);
569                         base = SchemaUtils.getComplexElementExtensionBase(base.getNode(),
570                                 symbolTable);
571                     }
572                 }
573                 // The exception class name is the name of the type
574             }
575         }
576         // Set the name of the exception and
577         // whether the exception is a complex type
578         MessageEntry me = symbolTable.getMessageEntry(faultMessageQName);
579         if (me != null) {
580             me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_DATA_TYPE,
581                     faultXmlType);
582             if (exceptionClassName != null) {
583                 me.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
584                         Boolean.TRUE);
585             } else {
586                 exceptionClassName = mapper.getExceptionType(faultMessageQName);
587                 if (exceptionClassName == null) {
588                     exceptionClassName = emitter.getJavaName(me.getQName());
589                 }
590             }
591             me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME,
592                     exceptionClassName);
593         }
594     }
595 
596     protected void determineInterfaceNames(SymbolTable symbolTable) {
597         Iterator it = symbolTable.getHashMap().values().iterator();
598         while (it.hasNext()) {
599             Vector v = (Vector) it.next();
600             for (int i = 0; i < v.size(); ++i) {
601                 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
602                 if (entry instanceof BindingEntry) {
603                     // The SEI (Service Endpoint Interface) name
604                     // is always the portType name.
605                     BindingEntry bEntry = (BindingEntry) entry;
606                     PortTypeEntry ptEntry = symbolTable.getPortTypeEntry(bEntry.getBinding().getPortType().getQName());
607                     String seiName = mapper.getServiceEndpointInterfaceName(ptEntry, bEntry);
608                     if (seiName == null) {
609                         seiName = ptEntry.getName();
610                     }
611                     bEntry.setDynamicVar(JavaBindingWriter.INTERFACE_NAME, seiName);
612                 } else if (entry instanceof ServiceEntry) {
613                     ServiceEntry sEntry = (ServiceEntry) entry;
614                     String siName = mapper.getServiceInterfaceName(sEntry);
615                     if (siName == null) {
616                         siName = sEntry.getName();
617                     }
618                     sEntry.setName(siName);
619                     Service service = sEntry.getService();
620                     // get ports
621                     Map portMap = service.getPorts();
622                     Iterator portIterator = portMap.values().iterator();
623                     while (portIterator.hasNext()) {
624                         Port p = (Port) portIterator.next();
625                         Binding binding = p.getBinding();
626                         BindingEntry bEntry =
627                                 symbolTable.getBindingEntry(binding.getQName());
628 
629                         // If this isn't a SOAP binding, skip it
630                         if (bEntry.getBindingType() != BindingEntry.TYPE_SOAP) {
631                             continue;
632                         }
633                         String portName = mapper.getPortName(p);
634                         if (portName == null) {
635                             portName = p.getName();
636                         }
637                         p.setName(portName);
638                     }
639                 }
640             }
641         }
642     } // determineInterfaceNames
643 
644     /***
645      * Messages, PortTypes, Bindings, and Services can share the same name.  If they do in this
646      * Definition, force their names to be suffixed with _PortType and _Service, respectively.
647      */
648     protected void resolveNameClashes(SymbolTable symbolTable) {
649         // Keep a list of anonymous types so we don't try to resolve them twice.
650         HashSet anonTypes = new HashSet();
651         Iterator it = symbolTable.getHashMap().values().iterator();
652         while (it.hasNext()) {
653             Vector v = new Vector((Vector) it.next());  // New vector we can temporarily add to it
654 
655             // Remove MessageEntries since they are not mapped
656             int index = 0;
657             while (index < v.size()) {
658                 if (v.elementAt(index) instanceof MessageEntry) {
659                     v.removeElementAt(index);
660                 } else {
661                     index++;
662                 }
663             }
664             if (v.size() > 1) {
665                 boolean resolve = true;
666                 // Common Special Case:
667                 // If a Type and Element have the same QName, and the Element
668                 // references the Type, then they are the same class so
669                 // don't bother mangling.
670                 if (v.size() == 2 &&
671                         ((v.elementAt(0) instanceof Element &&
672                         v.elementAt(1) instanceof Type) ||
673                         (v.elementAt(1) instanceof Element &&
674                         v.elementAt(0) instanceof Type))) {
675                     Element e = null;
676                     if (v.elementAt(0) instanceof Element) {
677                         e = (Element) v.elementAt(0);
678                     } else {
679                         e = (Element) v.elementAt(1);
680                     }
681                     BooleanHolder forElement = new BooleanHolder();
682                     QName eType = Utils.getTypeQName(e.getNode(), forElement, false);
683                     if (eType != null &&
684                             eType.equals(e.getQName()) &&
685                             !forElement.value)
686                         resolve = false;
687                 }
688 
689                 // Other Special Case:
690                 // If the names are already different, no mangling is needed.
691                 if (resolve) {
692                     resolve = false;  // Assume false
693                     String name = null;
694                     for (int i = 0; i < v.size() && !resolve; ++i) {
695                         SymTabEntry entry = (SymTabEntry) v.elementAt(i);
696                         if (entry instanceof MessageEntry ||
697                                 entry instanceof BindingEntry) {
698                             ; // Don't process these
699                         } else if (name == null) {
700                             name = entry.getName();
701                         } else if (name.equals(entry.getName())) {
702                             resolve = true;  // Need to do resolution
703                         }
704                     }
705                 }
706 
707                 // Full Mangle if resolution is necessary.
708                 if (resolve) {
709                     boolean firstType = true;
710                     for (int i = 0; i < v.size(); ++i) {
711                         SymTabEntry entry = (SymTabEntry) v.elementAt(i);
712                         if (entry instanceof Element) {
713                             entry.setName(mangleName(entry.getName(),
714                                     "_ElemType"));
715 
716                             // If this global element was defined using
717                             // an anonymous type, then need to change the
718                             // java name of the anonymous type to match.
719                             QName anonQName = new QName(entry.getQName().getNamespaceURI(),
720                                     SymbolTable.ANON_TOKEN +
721                                     entry.getQName().getLocalPart());
722                             TypeEntry anonType = symbolTable.getType(anonQName);
723                             if (anonType != null) {
724                                 anonType.setName(entry.getName());
725                                 anonTypes.add(anonType);
726                             }
727                         } else if (entry instanceof TypeEntry) {
728                             // Search all other types for java names that match this one.
729                             // The sameJavaClass method returns true if the java names are
730                             // the same (ignores [] ).
731                             if (firstType) {
732                                 firstType = false;
733                                 Iterator types = symbolTable.getTypeIndex().values().iterator();
734                                 while (types.hasNext()) {
735                                     TypeEntry type = (TypeEntry)
736                                             types.next();
737                                     if (type != entry && type.getBaseType() == null &&
738                                             sameJavaClass(entry.getName(), type.getName())) {
739                                         v.add(type);
740                                     }
741                                 }
742                             }
743                             // If this is an anonymous type, it's name was resolved in
744                             // the previous if block.  Don't reresolve it.
745                             if (!anonTypes.contains(entry)) {
746                                 entry.setName(mangleName(entry.getName(), "_Type"));
747                             }
748                         } else if (entry instanceof PortTypeEntry) {
749                             entry.setName(mangleName(entry.getName(), "_Port"));
750                         } else if (entry instanceof ServiceEntry) {
751                             entry.setName(mangleName(entry.getName(),
752                                     "_Service"));
753                         }
754                         // else if (entry instanceof MessageEntry) {
755                         //     we don't care about messages
756                         // }
757                         else if (entry instanceof BindingEntry) {
758                             BindingEntry bEntry = (BindingEntry) entry;
759 
760                             // If there is no literal use, then we never see a
761                             // class named directly from the binding name.  They
762                             // all have suffixes:  Stub, Skeleton, Impl.
763                             // If there IS literal use, then the SDI will be
764                             // named after the binding name, so there is the
765                             // possibility of a name clash.
766                             if (bEntry.hasLiteral()) {
767                                 entry.setName(mangleName(entry.getName(),
768                                         "_Binding"));
769                             }
770                         }
771                     }
772                 }
773             }
774         }
775     } // resolveNameClashes
776 
777     /***
778      * Change the indicated type name into a mangled form using the mangle string.
779      */
780     private String mangleName(String name, String mangle) {
781         int index = name.indexOf("[");
782         if (index >= 0) {
783             String pre = name.substring(0, index);
784             String post = name.substring(index);
785             return pre + mangle + post;
786         } else
787             return name + mangle;
788     }
789 
790     /***
791      * Returns true if same java class, ignore []
792      */
793     private boolean sameJavaClass(String one, String two) {
794         int index1 = one.indexOf("[");
795         int index2 = two.indexOf("[");
796         if (index1 > 0)
797             one = one.substring(0, index1);
798         if (index2 > 0)
799             two = two.substring(0, index2);
800         return one.equals(two);
801     }
802 
803     /***
804      * The --all flag is set on the command line (or generateAll(true) is called
805      * on WSDL2Java). Set all symbols as referenced (except nonSOAP bindings
806      * which we don't know how to deal with).
807      */
808     protected void setAllReferencesToTrue() {
809         Iterator it = symbolTable.getHashMap().values().iterator();
810         while (it.hasNext()) {
811             Vector v = (Vector) it.next();
812             for (int i = 0; i < v.size(); ++i) {
813                 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
814                 if (entry instanceof BindingEntry &&
815                         ((BindingEntry) entry).getBindingType() !=
816                         BindingEntry.TYPE_SOAP) {
817                     entry.setIsReferenced(false);
818                 } else {
819                     entry.setIsReferenced(true);
820                 }
821             }
822         }
823     } // setAllReferencesToTrue
824 
825     /***
826      * If a binding's type is not TYPE_SOAP, then we don't use that binding
827      * or that binding's portType.
828      */
829     protected void ignoreNonSOAPBindings(SymbolTable symbolTable) {
830         // Look at all uses of the portTypes.  If none of the portType's bindings are of type
831         // TYPE_SOAP, then turn off that portType's isReferenced flag.
832 
833         Vector unusedPortTypes = new Vector();
834         Vector usedPortTypes = new Vector();
835         Iterator it = symbolTable.getHashMap().values().iterator();
836         while (it.hasNext()) {
837             Vector v = (Vector) it.next();
838             for (int i = 0; i < v.size(); ++i) {
839                 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
840                 if (entry instanceof BindingEntry) {
841                     BindingEntry bEntry = (BindingEntry) entry;
842                     Binding binding = bEntry.getBinding();
843                     PortType portType = binding.getPortType();
844                     PortTypeEntry ptEntry =
845                             symbolTable.getPortTypeEntry(portType.getQName());
846                     if (bEntry.getBindingType() == BindingEntry.TYPE_SOAP) {
847                         // If a binding is of type TYPE_SOAP, then mark its portType used
848                         // (ie., add it to the usedPortTypes list.  If the portType was
849                         // previously marked as unused, unmark it (in other words, remove it
850                         // from the unusedPortTypes list).
851                         usedPortTypes.add(ptEntry);
852                         if (unusedPortTypes.contains(ptEntry)) {
853                             unusedPortTypes.remove(ptEntry);
854                         }
855                     } else {
856                         bEntry.setIsReferenced(false);
857 
858                         // If a binding is not of type TYPE_SOAP, then mark its portType as
859                         // unused ONLY if it hasn't already been marked as used.
860                         if (!usedPortTypes.contains(ptEntry)) {
861                             unusedPortTypes.add(ptEntry);
862                         }
863                     }
864                 }
865             }
866         }
867 
868         // Go through all the portTypes that are marked as unused and set their isReferenced flags
869         // to false.
870         for (int i = 0; i < unusedPortTypes.size(); ++i) {
871             PortTypeEntry ptEntry = (PortTypeEntry) unusedPortTypes.get(i);
872             ptEntry.setIsReferenced(false);
873         }
874     } // ignoreNonSOAPBindings
875 
876     protected void constructSignatures(SymbolTable symbolTable) {
877         Iterator it = symbolTable.getHashMap().values().iterator();
878         while (it.hasNext()) {
879             Vector v = (Vector) it.next();
880             for (int i = 0; i < v.size(); ++i) {
881                 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
882                 if (entry instanceof BindingEntry) {
883                     BindingEntry bEntry = (BindingEntry) entry;
884                     Binding binding = bEntry.getBinding();
885                     PortTypeEntry ptEntry =
886                             symbolTable.getPortTypeEntry(binding.getPortType().getQName());
887                     PortType portType = ptEntry.getPortType();
888                     Iterator operations = portType.getOperations().iterator();
889                     while (operations.hasNext()) {
890                         Operation operation = (Operation) operations.next();
891                         OperationType type = operation.getStyle();
892                         String name = mapper.getJavaMethodName(bEntry, operation);
893                         if (name == null) {
894                             name = operation.getName();
895                         }
896                         // OW Change Jerome
897                         // operation name must be set otherwise problem during matching beetween WSDD operation and java method
898                         operation.setName(name);
899                         // end
900                         Parameters parameters = bEntry.getParameters(operation);
901                         if (type == OperationType.SOLICIT_RESPONSE) {
902                             parameters.signature = "    // " + Messages.getMessage("invalidSolResp00", name);
903                             System.err.println(Messages.getMessage("invalidSolResp00", name));
904                         } else if (type == OperationType.NOTIFICATION) {
905                             parameters.signature = "    // " + Messages.getMessage("invalidNotif00", name);
906                             System.err.println(Messages.getMessage("invalidNotif00", name));
907                         } else { // ONE_WAY or REQUEST_RESPONSE
908                             if (parameters != null) {
909                                 String returnType = mapper.getJavaMethodReturnType(bEntry, operation);
910                                 // OW Change Guillaume
911                                 // parameters.returnParam may be null (no return value for the given operation)
912                                 if (returnType != null && parameters.returnParam != null) {
913                                     parameters.returnParam.getType().setName(returnType);
914                                 }
915                                 for (int j = 0; j < parameters.list.size(); ++j) {
916                                     Parameter p = (Parameter) parameters.list.get(j);
917                                     String paramType =
918                                             mapper.getJavaMethodParamType(bEntry, operation, j);
919                                     if (paramType != null) {
920                                         p.getType().setName(paramType);
921                                     }
922                                 }
923                                 parameters.signature = constructSignature(parameters, name);
924                             }
925                         }
926                     }
927                 }
928             }
929         }
930     } // constructSignatures
931 
932     /***
933      * Construct the signature, which is used by both the interface and the stub.
934      */
935     private String constructSignature(Parameters parms, String opName) {
936         String name = Utils.xmlNameToJava(opName);
937         String ret = "void";
938         if (parms != null && parms.returnParam != null) {
939             ret = Utils.getParameterTypeName(parms.returnParam);
940         }
941         String signature = "    public " + ret + " " + name + "(";
942         boolean needComma = false;
943         for (int i = 0; parms != null && i < parms.list.size(); ++i) {
944             Parameter p = (Parameter) parms.list.get(i);
945             if (needComma) {
946                 signature = signature + ", ";
947             } else {
948                 needComma = true;
949             }
950             String javifiedName = Utils.xmlNameToJava(p.getName());
951             if (p.getMode() == Parameter.IN) {
952                 signature = signature + Utils.getParameterTypeName(p) + " " + javifiedName;
953             } else {
954                 signature = signature + Utils.holder(p, emitter) + " "
955                         + javifiedName;
956             }
957         }
958         signature = signature + ") throws java.rmi.RemoteException";
959         if (parms != null && parms.faults != null) {
960             // Collect the list of faults into a single string, separated by commas.
961 
962             Iterator i = parms.faults.values().iterator();
963             while (i.hasNext()) {
964                 Fault fault = (Fault) i.next();
965                 String exceptionName =
966                         Utils.getFullExceptionName(fault.getMessage(), symbolTable);
967                 if (exceptionName != null) {
968                     signature = signature + ", " + exceptionName;
969                 }
970             }
971         }
972         return signature;
973     } // constructSignature
974 
975     /***
976      * Find all inout/out parameters and add a flag to the Type of that parameter saying a holder
977      * is needed.
978      */
979     protected void determineIfHoldersNeeded(SymbolTable symbolTable) {
980         Iterator it = symbolTable.getHashMap().values().iterator();
981         while (it.hasNext()) {
982             Vector v = (Vector) it.next();
983             for (int i = 0; i < v.size(); ++i) {
984                 if (v.get(i) instanceof BindingEntry) {
985                     // If entry is a BindingEntry, look at all the Parameters
986                     // in its portType
987                     BindingEntry bEntry = (BindingEntry) v.get(i);
988 //					  PortTypeEntry ptEntry =
989 //							  symbolTable.getPortTypeEntry(bEntry.getBinding().getPortType().getQName());
990                     Iterator operations =
991                             bEntry.getParameters().values().iterator();
992                     while (operations.hasNext()) {
993                         Parameters parms = (Parameters) operations.next();
994                         for (int j = 0; j < parms.list.size(); ++j) {
995                             Parameter p =
996                                     (Parameter) parms.list.get(j);
997 
998                             // If the given parameter is an inout or out parameter, then
999                             // set a HOLDER_IS_NEEDED flag using the dynamicVar design.
1000                             if (p.getMode() != Parameter.IN) {
1001                                 TypeEntry typeEntry = p.getType();
1002                                 typeEntry.setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
1003                                         Boolean.TRUE);
1004                                 //If this is a complex then set the HOLDER_IS_NEEDED
1005                                 //for the reftype too.
1006                                 if (!typeEntry.isSimpleType() && typeEntry.getRefType() != null) {
1007                                     typeEntry.getRefType().setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
1008                                             Boolean.TRUE);
1009                                 }
1010 
1011                                 // If the type is a DefinedElement, need to
1012                                 // set HOLDER_IS_NEEDED on the anonymous type.
1013                                 QName anonQName = SchemaUtils.
1014                                         getElementAnonQName(p.getType().getNode());
1015                                 if (anonQName != null) {
1016                                     TypeEntry anonType =
1017                                             symbolTable.getType(anonQName);
1018                                     if (anonType != null) {
1019                                         anonType.setDynamicVar(JavaTypeWriter.HOLDER_IS_NEEDED,
1020                                                 Boolean.TRUE);
1021                                     }
1022                                 }
1023                             }
1024                         }
1025                     }
1026                 }
1027             }
1028         }
1029     } // determineIfHoldersNeeded
1030 
1031     /***
1032      * Get TypeMapping to use for translating
1033      * QNames to java base types
1034      */
1035     BaseTypeMapping btm = null;
1036 
1037     public void setBaseTypeMapping(BaseTypeMapping btm) {
1038         this.btm = btm;
1039     }
1040 
1041     public BaseTypeMapping getBaseTypeMapping() {
1042         if (btm == null) {
1043             btm = new BaseTypeMapping() {
1044 
1045                 //TypeMapping defaultTM = DefaultTypeMappingImpl.getSingleton();
1046 
1047                 public String getBaseName(QName qNameIn) {
1048                     javax.xml.namespace.QName qName = new javax.xml.namespace.QName(qNameIn.getNamespaceURI(), qNameIn
1049                             .getLocalPart());
1050                     Class cls = emitter.getDefaultTypeMapping().getClassForQName(qName);
1051                     if (cls == null)
1052                         return null;
1053                     else
1054                         return JavaUtils.getTextClassName(cls.getName());
1055                 }
1056             };
1057         }
1058         return btm;
1059     }
1060 //    private Class getDeployerWriterClass(){
1061 //    	try{
1062 //            if(emitter.isUsedbyws4j2ee()){
1063 //            	return Class.forName("org.apache.geronimo.ews.ws4j2ee.toWs.ws.J2eeDeployWriter");
1064 //            }else
1065 //            	return  JavaDeployWriter.class;
1066 //        } catch (Exception e) {
1067 //        	e.printStackTrace();
1068 //            throw new RuntimeException(e);
1069 //        }
1070 //    }
1071 }