Source code: org/apache/axis/wsdl/toJava/JavaGeneratorFactory.java
1 /*
2 * Copyright 2001-2004 The Apache Software Foundation.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.apache.axis.wsdl.toJava;
17
18 import org.apache.axis.components.logger.LogFactory;
19 import org.apache.axis.utils.JavaUtils;
20 import org.apache.axis.utils.Messages;
21 import org.apache.axis.wsdl.gen.Generator;
22 import org.apache.axis.wsdl.gen.GeneratorFactory;
23 import org.apache.axis.wsdl.gen.NoopGenerator;
24 import org.apache.axis.wsdl.symbolTable.BaseTypeMapping;
25 import org.apache.axis.wsdl.symbolTable.BindingEntry;
26 import org.apache.axis.wsdl.symbolTable.ContainedAttribute;
27 import org.apache.axis.wsdl.symbolTable.Element;
28 import org.apache.axis.wsdl.symbolTable.ElementDecl;
29 import org.apache.axis.wsdl.symbolTable.FaultInfo;
30 import org.apache.axis.wsdl.symbolTable.MessageEntry;
31 import org.apache.axis.wsdl.symbolTable.Parameter;
32 import org.apache.axis.wsdl.symbolTable.Parameters;
33 import org.apache.axis.wsdl.symbolTable.PortTypeEntry;
34 import org.apache.axis.wsdl.symbolTable.SchemaUtils;
35 import org.apache.axis.wsdl.symbolTable.ServiceEntry;
36 import org.apache.axis.wsdl.symbolTable.SymTabEntry;
37 import org.apache.axis.wsdl.symbolTable.SymbolTable;
38 import org.apache.axis.wsdl.symbolTable.Type;
39 import org.apache.axis.wsdl.symbolTable.TypeEntry;
40 import org.apache.commons.logging.Log;
41
42 import javax.wsdl.Binding;
43 import javax.wsdl.Definition;
44 import javax.wsdl.Fault;
45 import javax.wsdl.Message;
46 import javax.wsdl.Operation;
47 import javax.wsdl.OperationType;
48 import javax.wsdl.Port;
49 import javax.wsdl.PortType;
50 import javax.wsdl.Service;
51 import javax.xml.namespace.QName;
52 import javax.xml.rpc.holders.BooleanHolder;
53 import java.io.IOException;
54 import java.lang.reflect.Constructor;
55 import java.util.ArrayList;
56 import java.util.HashMap;
57 import java.util.HashSet;
58 import java.util.Iterator;
59 import java.util.List;
60 import java.util.Map;
61 import java.util.Vector;
62
63 /**
64 * This is Wsdl2java's implementation of the GeneratorFactory
65 */
66 public class JavaGeneratorFactory implements GeneratorFactory {
67 private static final Log log_ =
68 LogFactory.getLog(JavaGeneratorFactory.class.getName());
69
70 /** Field emitter */
71 protected Emitter emitter;
72
73 /** Field symbolTable */
74 protected SymbolTable symbolTable;
75
76 /** Field COMPLEX_TYPE_FAULT */
77 public static String COMPLEX_TYPE_FAULT = "ComplexTypeFault";
78
79 /** Field EXCEPTION_CLASS_NAME */
80 public static String EXCEPTION_CLASS_NAME = "ExceptionClassName";
81
82 /** Field EXCEPTION_DATA_TYPE */
83 public static String EXCEPTION_DATA_TYPE = "ExceptionDataType";
84
85 /* Name suffixes for collision */
86 private static final String SERVICE_SUFFIX = "_Service";
87 private static final String PORT_TYPE_SUFFIX = "_PortType"; // "_Port" (Axis classic) --> "_PortType" (JAX-RPC 1.1)
88 private static final String TYPE_SUFFIX = "_Type";
89 private static final String ELEMENT_SUFFIX = "_Element"; // "_ElemType (Axis classic) --> "_Element" (JAX-RPC 1.1)
90 private static final String EXCEPTION_SUFFIX = "_Exception";
91 private static final String BINDING_SUFFIX = "_Binding";
92
93
94 /**
95 * Default constructor. Note that this class is unusable until setEmitter
96 * is called.
97 */
98 public JavaGeneratorFactory() {
99 addGenerators();
100 } // ctor
101
102 /**
103 * Constructor JavaGeneratorFactory
104 *
105 * @param emitter
106 */
107 public JavaGeneratorFactory(Emitter emitter) {
108
109 this.emitter = emitter;
110
111 addGenerators();
112 } // ctor
113
114 /**
115 * Method setEmitter
116 *
117 * @param emitter
118 */
119 public void setEmitter(Emitter emitter) {
120 this.emitter = emitter;
121 } // setEmitter
122
123 /**
124 * Method addGenerators
125 */
126 private void addGenerators() {
127
128 addMessageGenerators();
129 addPortTypeGenerators();
130 addBindingGenerators();
131 addServiceGenerators();
132 addTypeGenerators();
133 addDefinitionGenerators();
134 } // addGenerators
135
136 /**
137 * These addXXXGenerators are called by the constructor.
138 * If an extender of this factory wants to CHANGE the set
139 * of generators that are called per WSDL construct, they
140 * should override these addXXXGenerators methods. If all
141 * an extender wants to do is ADD a generator, then the
142 * extension should simply call addGenerator.
143 * (NOTE: It doesn't quite work this way, yet. Only the
144 * Definition generators fit this model at this point in
145 * time.)
146 */
147 protected void addMessageGenerators() {
148 } // addMessageGenerators
149
150 /**
151 * Method addPortTypeGenerators
152 */
153 protected void addPortTypeGenerators() {
154 } // addPortTypeGenerators
155
156 /**
157 * Method addBindingGenerators
158 */
159 protected void addBindingGenerators() {
160 } // addBindingGenerators
161
162 /**
163 * Method addServiceGenerators
164 */
165 protected void addServiceGenerators() {
166 } // addServiceGenerators
167
168 /**
169 * Method addTypeGenerators
170 */
171 protected void addTypeGenerators() {
172 } // addTypeGenerators
173
174 /**
175 * Method addDefinitionGenerators
176 */
177 protected void addDefinitionGenerators() {
178
179 addGenerator(Definition.class, JavaDefinitionWriter.class); // for faults
180 addGenerator(Definition.class,
181 JavaDeployWriter.class); // for deploy.wsdd
182 addGenerator(Definition.class,
183 JavaUndeployWriter.class); // for undeploy.wsdd
184 addGenerator(Definition.class,
185 JavaBuildFileWriter.class); //add a build file writer
186
187 } // addDefinitionGenerators
188
189
190 /**
191 * Do the Wsdl2java generator pass:
192 * - resolve name clashes
193 * - construct signatures
194 *
195 * @param def
196 * @param symbolTable
197 */
198 public void generatorPass(Definition def, SymbolTable symbolTable) {
199
200 this.symbolTable = symbolTable;
201
202 javifyNames(symbolTable);
203 setFaultContext(symbolTable);
204 resolveNameClashes(symbolTable);
205 determineInterfaceNames(symbolTable);
206
207 if (emitter.isAllWanted()) {
208 setAllReferencesToTrue();
209 } else {
210 ignoreNonSOAPBindings(symbolTable);
211 }
212
213 constructSignatures(symbolTable);
214 determineIfHoldersNeeded(symbolTable);
215 } // generatorPass
216
217 /** Since Wsdl2java doesn't emit anything for Messages, return the No-op generator. */
218 private Writers messageWriters = new Writers();
219
220 /**
221 * Method getGenerator
222 *
223 * @param message
224 * @param symbolTable
225 * @return
226 */
227 public Generator getGenerator(Message message, SymbolTable symbolTable) {
228 if (include(message.getQName())) {
229 MessageEntry mEntry = symbolTable.getMessageEntry(message.getQName());
230 messageWriters.addStuff(new NoopGenerator(), mEntry, symbolTable);
231 return messageWriters;
232 }
233 else {
234 return new NoopGenerator();
235 }
236 } // getGenerator
237
238 /** Return Wsdl2java's JavaPortTypeWriter object. */
239 private Writers portTypeWriters = new Writers();
240
241 /**
242 * Method getGenerator
243 *
244 * @param portType
245 * @param symbolTable
246 * @return
247 */
248 public Generator getGenerator(PortType portType, SymbolTable symbolTable) {
249 if (include(portType.getQName())) {
250 PortTypeEntry ptEntry =
251 symbolTable.getPortTypeEntry(portType.getQName());
252 portTypeWriters.addStuff(new NoopGenerator(), ptEntry, symbolTable);
253 return portTypeWriters;
254 }
255 else {
256 return new NoopGenerator();
257 }
258 } // getGenerator
259
260 /** Return Wsdl2java's JavaBindingWriter object. */
261 protected Writers bindingWriters = new Writers();
262
263 /**
264 * Method getGenerator
265 *
266 * @param binding
267 * @param symbolTable
268 * @return
269 */
270 public Generator getGenerator(Binding binding, SymbolTable symbolTable) {
271 if (include(binding.getQName())) {
272 Generator writer = new JavaBindingWriter(emitter, binding,
273 symbolTable);
274 BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName());
275 bindingWriters.addStuff(writer, bEntry, symbolTable);
276 return bindingWriters;
277 }
278 else {
279 return new NoopGenerator();
280 }
281 } // getGenerator
282
283 /** Return Wsdl2java's JavaServiceWriter object. */
284 protected Writers serviceWriters = new Writers();
285
286 /**
287 * Method getGenerator
288 *
289 * @param service
290 * @param symbolTable
291 * @return
292 */
293 public Generator getGenerator(Service service, SymbolTable symbolTable) {
294 if (include(service.getQName())) {
295 Generator writer = new JavaServiceWriter(emitter, service,
296 symbolTable);
297 ServiceEntry sEntry = symbolTable.getServiceEntry(service.getQName());
298 serviceWriters.addStuff(writer, sEntry, symbolTable);
299 return serviceWriters;
300 }
301 else {
302 return new NoopGenerator();
303 }
304 } // getGenerator
305
306 /** Return Wsdl2java's JavaTypeWriter object. */
307 private Writers typeWriters = new Writers();
308
309 /**
310 * Method getGenerator
311 *
312 * @param type
313 * @param symbolTable
314 * @return
315 */
316 public Generator getGenerator(TypeEntry type, SymbolTable symbolTable) {
317 if (include(type.getQName())) {
318 Generator writer = new JavaTypeWriter(emitter, type, symbolTable);
319 typeWriters.addStuff(writer, type, symbolTable);
320 return typeWriters;
321 }
322 else {
323 return new NoopGenerator();
324 }
325 } // getGenerator
326
327 /** Return Wsdl2java's JavaDefinitionWriter object. */
328 private Writers defWriters = new Writers();
329
330 /**
331 * Method getGenerator
332 *
333 * @param definition
334 * @param symbolTable
335 * @return
336 */
337 public Generator getGenerator(Definition definition,
338 SymbolTable symbolTable) {
339 if (include(definition.getQName())) {
340 defWriters.addStuff(null, definition, symbolTable);
341 return defWriters;
342 }
343 else {
344 return new NoopGenerator();
345 }
346 } // getGenerator
347
348 // Hack class just to play with the idea of adding writers
349
350 /**
351 * Class Writers
352 *
353 * @version %I%, %G%
354 */
355 protected class Writers implements Generator {
356
357 /** Field writers */
358 Vector writers = new Vector();
359
360 /** Field symbolTable */
361 SymbolTable symbolTable = null;
362
363 /** Field baseWriter */
364 Generator baseWriter = null;
365
366 // entry or def, but not both, will be a parameter.
367
368 /** Field entry */
369 SymTabEntry entry = null;
370
371 /** Field def */
372 Definition def = null;
373
374 /**
375 * Method addGenerator
376 *
377 * @param writer
378 */
379 public void addGenerator(Class writer) {
380 writers.add(writer);
381 } // addWriter
382
383 /**
384 * Method addStuff
385 *
386 * @param baseWriter
387 * @param entry
388 * @param symbolTable
389 */
390 public void addStuff(Generator baseWriter, SymTabEntry entry,
391 SymbolTable symbolTable) {
392
393 this.baseWriter = baseWriter;
394 this.entry = entry;
395 this.symbolTable = symbolTable;
396 } // addStuff
397
398 /**
399 * Method addStuff
400 *
401 * @param baseWriter
402 * @param def
403 * @param symbolTable
404 */
405 public void addStuff(Generator baseWriter, Definition def,
406 SymbolTable symbolTable) {
407
408 this.baseWriter = baseWriter;
409 this.def = def;
410 this.symbolTable = symbolTable;
411 } // addStuff
412
413 /**
414 * Method generate
415 *
416 * @throws IOException
417 */
418 public void generate() throws IOException {
419
420 if (baseWriter != null) {
421 baseWriter.generate();
422 }
423
424 Class[] formalArgs;
425 Object[] actualArgs;
426
427 if (entry != null) {
428 formalArgs = new Class[]{Emitter.class, entry.getClass(),
429 SymbolTable.class};
430 actualArgs = new Object[]{emitter, entry, symbolTable};
431 } else {
432 formalArgs = new Class[]{Emitter.class, Definition.class,
433 SymbolTable.class};
434 actualArgs = new Object[]{emitter, def, symbolTable};
435 }
436
437 for (int i = 0; i < writers.size(); ++i) {
438 Class wClass = (Class) writers.get(i);
439 Generator gen;
440
441 try {
442 Constructor ctor = wClass.getConstructor(formalArgs);
443
444 gen = (Generator) ctor.newInstance(actualArgs);
445 } catch (Throwable t) {
446 throw new IOException(Messages.getMessage("exception01",
447 t.getMessage()));
448 }
449
450 gen.generate();
451 }
452 } // generate
453 } // class Writers
454
455 /**
456 * Method addGenerator
457 *
458 * @param wsdlClass
459 * @param generator
460 */
461 public void addGenerator(Class wsdlClass, Class generator) {
462
463 // This is just a hack right now... it just works with Service
464 if (Message.class.isAssignableFrom(wsdlClass)) {
465 messageWriters.addGenerator(generator);
466 } else if (PortType.class.isAssignableFrom(wsdlClass)) {
467 portTypeWriters.addGenerator(generator);
468 } else if (Binding.class.isAssignableFrom(wsdlClass)) {
469 bindingWriters.addGenerator(generator);
470 } else if (Service.class.isAssignableFrom(wsdlClass)) {
471 serviceWriters.addGenerator(generator);
472 } else if (TypeEntry.class.isAssignableFrom(wsdlClass)) {
473 typeWriters.addGenerator(generator);
474 } else if (Definition.class.isAssignableFrom(wsdlClass)) {
475 defWriters.addGenerator(generator);
476 }
477 } // addGenerator
478
479 /**
480 * Fill in the names of each SymTabEntry with the javaified name.
481 * Note: This method also ensures that anonymous types are
482 * given unique java type names.
483 *
484 * @param symbolTable
485 */
486 protected void javifyNames(SymbolTable symbolTable) {
487
488 int uniqueNum = 0;
489 HashMap anonQNames = new HashMap();
490 Iterator it = symbolTable.getHashMap().values().iterator();
491
492 while (it.hasNext()) {
493 Vector v = (Vector) it.next();
494
495 for (int i = 0; i < v.size(); ++i) {
496 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
497
498 if (entry.getName() != null) {
499 continue;
500 }
501
502 // Use the type or the referenced type's QName to generate the java name.
503 if (entry instanceof TypeEntry) {
504 uniqueNum = javifyTypeEntryName(symbolTable, (TypeEntry) entry, anonQNames, uniqueNum);
505 }
506
507 // If it is not a type, then use this entry's QName to
508 // generate its name.
509 else {
510 entry.setName(emitter.getJavaName(entry.getQName()));
511 }
512 }
513 }
514 } // javifyNames
515
516 /** Refactored to call recursively for JAX-RPC 1.1 spec 4.2.5. */
517 protected int javifyTypeEntryName(SymbolTable symbolTable, TypeEntry entry, HashMap anonQNames, int uniqueNum) {
518 TypeEntry tEntry = entry;
519 String dims = tEntry.getDimensions();
520 TypeEntry refType = tEntry.getRefType();
521 while (refType != null) {
522 tEntry = refType;
523 dims += tEntry.getDimensions();
524 refType = tEntry.getRefType();
525 }
526
527 TypeEntry te = tEntry;
528 while (te != null) {
529 TypeEntry base = SchemaUtils.getBaseType(te, symbolTable);
530 if (base == null)
531 break;
532
533 uniqueNum = javifyTypeEntryName(symbolTable, base, anonQNames, uniqueNum);
534
535 if (Utils.getEnumerationBaseAndValues(te.getNode(), symbolTable) == null
536 &&SchemaUtils.getComplexElementExtensionBase(te.getNode(), symbolTable) == null
537 && te.getContainedAttributes() == null) {
538 if(!SchemaUtils.isSimpleTypeWithUnion(te.getNode())) {
539 if (base.isSimpleType()) {
540 // Case 1:
541 // <simpleType name="mySimpleStringType">
542 // <restriction base="xs:string">
543 // </restriction>
544 // </simpleType>
545 te.setSimpleType(true);
546 te.setName(base.getName());
547 te.setRefType(base);
548 }
549
550 if (base.isBaseType()) {
551 // Case 2:
552 // <simpleType name="FooString">
553 // <restriction base="foo:mySimpleStringType">
554 // </restriction>
555 // </simpleType>
556 te.setBaseType(true);
557 te.setName(base.getName());
558 te.setRefType(base);
559 }
560 }
561 }
562
563 if (!te.isSimpleType())
564 break;
565
566 te = base;
567 }
568
569 // Need to javify the ref'd TypeEntry if it was not
570 // already processed
571 if (tEntry.getName() == null) {
572 boolean processed = false; // true if the java name is already determined
573 // Get the QName of the ref'd TypeEntry, which
574 // is will be used to javify the name
575 QName typeQName = tEntry.getQName();
576
577 // In case of <xsd:list itemType="...">,
578 // set typeQName to the value of the itemType attribute.
579 QName itemType = SchemaUtils.getListItemType(tEntry.getNode());
580 if (itemType != null) {
581 // Get the typeEntry so we know the absolute base type
582 TypeEntry itemEntry = symbolTable.getTypeEntry(itemType, false);
583 // TODO - If the itemEntry is not found, we need to throw
584 // an exception. "Item is referenced, but not defined"
585 javifyTypeEntryName(symbolTable, itemEntry, anonQNames, uniqueNum);
586 // Grab the referenced type, If it's there.
587 TypeEntry refedEntry = itemEntry.getRefType();
588 QName baseName = refedEntry == null ? itemEntry.getQName() :
589 refedEntry.getQName();
590 typeQName = new QName(baseName.getNamespaceURI(),
591 baseName.getLocalPart() + "[]");
592 }
593
594 if (emitter.isDeploy()) {
595 Class class1 = (Class) emitter.getQName2ClassMap().get(typeQName);
596 if (class1 != null && !class1.isArray()) {
597 tEntry.setName(getJavaClassName(class1));
598 processed = true;
599 }
600 }
601
602 if (!processed) {
603 if ((typeQName.getLocalPart().
604 indexOf(SymbolTable.ANON_TOKEN) < 0)) {
605 // Normal Case: The ref'd type is not anonymous
606 // Simply construct the java name from
607 // the qName
608 tEntry.setName(emitter.getJavaName(typeQName));
609 } else {
610 // This is an anonymous type name.
611 // Axis uses '>' as a nesting token to generate
612 // unique qnames for anonymous types.
613 // Only consider the localName after the last '>'
614 // when generating the java name
615 // String localName = typeQName.getLocalPart();
616 // localName =
617 // localName.substring(
618 // localName.lastIndexOf(
619 // SymbolTable.ANON_TOKEN)+1);
620 // typeQName = new QName(typeQName.getNamespaceURI(),
621 // localName);
622 String localName = typeQName.getLocalPart();
623
624 // Check to see if this is an anonymous type,
625 // if it is, replace Axis' ANON_TOKEN with
626 // an underscore to make sure we don't run
627 // into name collisions with similarly named
628 // non-anonymous types
629 StringBuffer sb = new StringBuffer(localName);
630 int aidx;
631
632 while ((aidx = sb.toString().indexOf(SymbolTable.ANON_TOKEN)) > -1) {
633 sb.replace(aidx, aidx + SymbolTable.ANON_TOKEN.length(), "");
634 char c = sb.charAt(aidx);
635 if (Character.isLetter(c) && Character.isLowerCase(c)) {
636 sb.setCharAt(aidx, Character.toUpperCase(c));
637 }
638 }
639
640 localName = sb.toString();
641 typeQName = new QName(typeQName.getNamespaceURI(),
642 localName);
643
644 if (emitter.isTypeCollisionProtection() &&
645 !emitter.getNamespaceExcludes().contains(new NamespaceSelector(typeQName.getNamespaceURI()))) {
646 // If there is already an existing type,
647 // there will be a collision.
648 // If there is an existing anon type,
649 // there will be a collision.
650 // In both cases, mangle the name.
651 if (symbolTable.getType(typeQName) != null ||
652 anonQNames.get(typeQName) != null) {
653 localName += "Type" + uniqueNum++;
654 typeQName =
655 new QName(typeQName.getNamespaceURI(),
656 localName);
657 }
658
659 anonQNames.put(typeQName, typeQName);
660 }
661
662 // Now set the name with the constructed qname
663 tEntry.setName(emitter.getJavaName(typeQName));
664 }
665 } // if (!processed)
666
667 Vector elements = tEntry.getContainedElements();
668 if (elements != null) {
669 for (int i = 0; i < elements.size(); i++) {
670 ElementDecl elem = (ElementDecl) elements.get(i);
671 String varName = emitter.getJavaVariableName(typeQName, elem.getQName(), true);
672 elem.setName(varName);
673 }
674 }
675
676 Vector attributes = tEntry.getContainedAttributes();
677 if (attributes != null) {
678 for (int i = 0; i < attributes.size(); i++) {
679 ContainedAttribute attr = (ContainedAttribute) attributes.get(i);
680 String varName = emitter.getJavaVariableName(typeQName, attr.getQName(), false);
681 attr.setName(varName);
682 }
683 }
684 }
685
686 // Set the entry with the same name as the ref'd entry
687 // but add the appropriate amount of dimensions
688 entry.setName(tEntry.getName() + dims);
689
690 return uniqueNum;
691 }
692
693 /**
694 * Gets class name from Java class.
695 * If the class is an array, get its component type's name
696 * @param clazz a java class
697 * @return the class name in string
698 */
699 private static String getJavaClassName(Class clazz) {
700 Class class1 = clazz;
701
702 while (class1.isArray()) {
703 class1 = class1.getComponentType();
704 }
705
706 String name = class1.getName();
707 name.replace('$', '.');
708 return name;
709 }
710
711 /**
712 * setFaultContext:
713 * Processes the symbol table and sets the COMPLEX_TYPE_FAULT
714 * on each TypeEntry that is a complexType and is referenced in
715 * a fault message. TypeEntries that are the base or derived
716 * from such a TypeEntry are also marked with COMPLEX_TYPE_FAULT.
717 * The containing MessageEntry is marked with cOMPLEX_TYPE_FAULT, and
718 * all MessageEntries for faults are tagged with the
719 * EXCEPTION_CLASS_NAME variable, which indicates the java exception
720 * class name.
721 *
722 * @param symbolTable SymbolTable
723 */
724 private void setFaultContext(SymbolTable symbolTable) {
725
726 Iterator it = symbolTable.getHashMap().values().iterator();
727
728 while (it.hasNext()) {
729 Vector v = (Vector) it.next();
730
731 for (int i = 0; i < v.size(); ++i) {
732 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
733
734 // Inspect each BindingEntry in the Symbol Table
735 if (entry instanceof BindingEntry) {
736 BindingEntry bEntry = (BindingEntry) entry;
737 HashMap allOpFaults = bEntry.getFaults();
738 Iterator ops = allOpFaults.values().iterator();
739
740 // set the context for all faults for this binding.
741 while (ops.hasNext()) {
742 ArrayList faults = (ArrayList) ops.next();
743
744 for (int j = 0; j < faults.size(); ++j) {
745 FaultInfo info = (FaultInfo) faults.get(j);
746
747 setFaultContext(info, symbolTable);
748 }
749 }
750 }
751 }
752 }
753 } // setFaultContext
754
755 /**
756 * setFaultContext:
757 * Helper routine for the setFaultContext method above.
758 * Examines the indicated fault and sets COMPLEX_TYPE_FAULT
759 * EXCEPTION_DATA_TYPE and EXCEPTION_CLASS_NAME as appropriate.
760 *
761 * @param fault FaultInfo to analyze
762 * @param symbolTable SymbolTable
763 */
764 private void setFaultContext(FaultInfo fault, SymbolTable symbolTable) {
765
766 QName faultXmlType = null;
767 Vector parts = new Vector();
768
769 // Get the parts of the fault's message.
770 // An IOException is thrown if the parts cannot be
771 // processed. Skip such parts for this analysis
772 try {
773 symbolTable.getParametersFromParts(
774 parts, fault.getMessage().getOrderedParts(null), false,
775 fault.getName(), null);
776 } catch (IOException e) {
777 }
778
779 // Inspect each TypeEntry referenced in a Fault Message Part
780 String exceptionClassName = null;
781
782 for (int j = 0; j < parts.size(); j++) {
783 TypeEntry te = ((Parameter) (parts.elementAt(j))).getType();
784
785 // If the TypeEntry is an element, advance to the type.
786 // This occurs if the message part uses the element= attribute
787 TypeEntry elementTE = null;
788
789 if (te instanceof Element) {
790 elementTE = te;
791 te = te.getRefType();
792 }
793
794 // remember the QName of the type.
795 faultXmlType = te.getQName();
796
797 // Determine if the te should be processed using the
798 // simple type mapping or the complex type mapping
799 // NOTE: treat array types as simple types
800 if ((te.getBaseType() != null) || te.isSimpleType()
801 || ((te.getDimensions().length() > 0)
802 && (te.getRefType().getBaseType() != null))) {
803
804 // Simple Type Exception
805 } else {
806
807 // Complex Type Exception
808 Boolean isComplexFault = (Boolean) te.getDynamicVar(
809 JavaGeneratorFactory.COMPLEX_TYPE_FAULT);
810
811 if ((isComplexFault == null) || !isComplexFault.booleanValue()) {
812
813 // Mark the type as a complex type fault
814 te.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
815 Boolean.TRUE);
816
817 if (elementTE != null) {
818 te.setDynamicVar(
819 JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
820 Boolean.TRUE);
821 }
822
823 // Mark all derived types as Complex Faults
824 HashSet derivedSet =
825 org.apache.axis.wsdl.symbolTable.Utils.getDerivedTypes(
826 te, symbolTable);
827 Iterator derivedI = derivedSet.iterator();
828
829 while (derivedI.hasNext()) {
830 TypeEntry derivedTE = (TypeEntry) derivedI.next();
831
832 derivedTE.setDynamicVar(
833 JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
834 Boolean.TRUE);
835 }
836
837 // Mark all base types as Complex Faults
838 TypeEntry base =
839 SchemaUtils.getComplexElementExtensionBase(te.getNode(),
840 symbolTable);
841
842 while (base != null) {
843 base.setDynamicVar(
844 JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
845 Boolean.TRUE);
846
847 base = SchemaUtils.getComplexElementExtensionBase(
848 base.getNode(), symbolTable);
849 }
850 }
851
852 // The exception class name is the name of the type
853 exceptionClassName = te.getName();
854 }
855 }
856
857 String excName = getExceptionJavaNameHook(fault.getMessage().getQName()); // for derived class
858 if (excName != null) {
859 exceptionClassName = excName;
860 }
861
862 // Set the name of the exception and
863 // whether the exception is a complex type
864 MessageEntry me =
865 symbolTable.getMessageEntry(fault.getMessage().getQName());
866
867 if (me != null) {
868 me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_DATA_TYPE,
869 faultXmlType);
870
871 if (exceptionClassName != null) {
872 me.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT,
873 Boolean.TRUE);
874 me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME,
875 exceptionClassName);
876 } else {
877 me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME,
878 emitter.getJavaName(me.getQName()));
879 }
880 }
881 }
882
883 protected String getExceptionJavaNameHook(QName qname) {
884 return null;
885 }
886
887 /**
888 * Method determineInterfaceNames
889 *
890 * @param symbolTable
891 */
892 protected void determineInterfaceNames(SymbolTable symbolTable) {
893
894 Iterator it = symbolTable.getHashMap().values().iterator();
895
896 while (it.hasNext()) {
897 Vector v = (Vector) it.next();
898
899 for (int i = 0; i < v.size(); ++i) {
900 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
901
902 if (entry instanceof BindingEntry) {
903
904 // The SEI (Service Endpoint Interface) name
905 // is always the portType name.
906 BindingEntry bEntry = (BindingEntry) entry;
907 PortTypeEntry ptEntry = symbolTable.getPortTypeEntry(
908 bEntry.getBinding().getPortType().getQName());
909
910 String seiName = getServiceEndpointInterfaceJavaNameHook(ptEntry, bEntry);
911 if (seiName == null) {
912 seiName = ptEntry.getName();
913 }
914
915 bEntry.setDynamicVar(JavaBindingWriter.INTERFACE_NAME,
916 seiName);
917 } else if (entry instanceof ServiceEntry) {
918 ServiceEntry sEntry = (ServiceEntry) entry;
919 String siName = getServiceInterfaceJavaNameHook(sEntry); // for derived class
920 if (siName != null) {
921 sEntry.setName(siName);
922 }
923
924 Service service = sEntry.getService();
925 Map portMap = service.getPorts();
926 Iterator portIterator = portMap.values().iterator();
927
928 while (portIterator.hasNext()) {
929 Port p = (Port) portIterator.next();
930
931 Binding binding = p.getBinding();
932 BindingEntry bEntry =
933 symbolTable.getBindingEntry(binding.getQName());
934
935 // If this isn't a SOAP binding, skip it
936 if (bEntry.getBindingType() != BindingEntry.TYPE_SOAP) {
937 continue;
938 }
939
940 String portName = getPortJavaNameHook(p.getName()); // for derived class
941 if (portName != null) {
942 bEntry.setDynamicVar(JavaServiceWriter.PORT_NAME + ":" + p.getName(),
943 portName);
944 }
945 }
946 }
947 }
948 }
949 } // determineInterfaceNames
950
951 protected String getServiceEndpointInterfaceJavaNameHook(PortTypeEntry ptEntry, BindingEntry bEntry) {
952 return null;
953 }
954
955 protected String getServiceInterfaceJavaNameHook(ServiceEntry sEntry) {
956 return null;
957 }
958
959 protected String getPortJavaNameHook(String portName) {
960 return null;
961 }
962
963 /**
964 * Messages, PortTypes, Bindings, and Services can share the same name. If they do in this
965 * Definition, force their names to be suffixed with _PortType and _Service, respectively.
966 *
967 * @param symbolTable
968 */
969 protected void resolveNameClashes(SymbolTable symbolTable) {
970
971 // Keep a list of anonymous types so we don't try to resolve them twice.
972 HashSet anonTypes = new HashSet();
973 List collisionCandidates = new ArrayList(); // List of vector of SymbolTable entry
974
975 List localParts = new ArrayList(); // all localparts in all symboltable entries
976 for (Iterator i = symbolTable.getHashMap().keySet().iterator(); i.hasNext(); ) {
977 QName qName = (QName)i.next();
978 String localPart = qName.getLocalPart();
979 if (!localParts.contains(localPart))
980 localParts.add(localPart);
981 }
982
983 Map pkg2NamespacesMap = emitter.getNamespaces().getPkg2NamespacesMap();
984 for (Iterator i = pkg2NamespacesMap.values().iterator(); i.hasNext(); ) {
985 Vector namespaces = (Vector)i.next(); // namepaces mapped to same package
986
987 // Combine entry vectors, which have the same entry name, into a new entry vector.
988 for (int j = 0; j < localParts.size(); j++) {
989 Vector v = new Vector();
990 for (int k = 0; k < namespaces.size(); k++) {
991 QName qName = new QName((String)namespaces.get(k), (String)localParts.get(j));
992 if (symbolTable.getHashMap().get(qName) != null) {
993 v.addAll((Vector)symbolTable.getHashMap().get(qName));
994 }
995 }
996 if(v.size()>0) {
997 collisionCandidates.add(v);
998 }
999 }
1000 }
1001 Iterator it = collisionCandidates.iterator();
1002
1003 while (it.hasNext()) {
1004 Vector v = new Vector(
1005 (Vector) it.next()); // New vector we can temporarily add to it
1006
1007 // Remove MessageEntries since they are not mapped
1008 int index = 0;
1009
1010 while (index < v.size()) {
1011 if (v.elementAt(index) instanceof MessageEntry) {
1012 // Need to resolve a Exception message.
1013 MessageEntry msgEntry = (MessageEntry) v.elementAt(index);
1014 if (msgEntry.getDynamicVar(EXCEPTION_CLASS_NAME) == null) {
1015 v.removeElementAt(index);
1016 } else {
1017 index++;
1018 }
1019 } else {
1020 index++;
1021 }
1022 }
1023
1024 if (v.size() > 1) {
1025 boolean resolve = true;
1026
1027 // Common Special Case:
1028 // If a Type and Element have the same QName, and the Element
1029 // references the Type, then they are the same class so
1030 // don't bother mangling.
1031 if (v.size() == 2 &&
1032 ((v.elementAt(0) instanceof Element &&
1033 v.elementAt(1) instanceof Type) ||
1034 (v.elementAt(1) instanceof Element &&
1035 v.elementAt(0) instanceof Type))) {
1036 Element e;
1037 if (v.elementAt(0) instanceof Element) {
1038 e = (Element) v.elementAt(0);
1039 } else {
1040 e = (Element) v.elementAt(1);
1041 }
1042
1043 BooleanHolder forElement = new BooleanHolder();
1044 QName eType = Utils.getTypeQName(e.getNode(),
1045 forElement, false);
1046
1047 if ((eType != null) && eType.equals(e.getQName())
1048 && !forElement.value) {
1049 resolve = false;
1050 }
1051 }
1052
1053 // Other Special Case:
1054 // If the names are already different, no mangling is needed.
1055 if (resolve) {
1056 resolve = false; // Assume false
1057
1058 String name = null;
1059
1060 for (int i = 0; (i < v.size()) && !resolve; ++i) {
1061 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
1062
1063 if ((entry instanceof MessageEntry)
1064 || (entry instanceof BindingEntry)) {
1065 // Need to resolve a exception class name
1066 String exceptionClassName = (String) entry.getDynamicVar(EXCEPTION_CLASS_NAME);
1067 if (exceptionClassName != null) {
1068 if (name == null) {
1069 name = exceptionClassName;
1070 } else if (name.equals(exceptionClassName)) {
1071 resolve = true;
1072 }
1073 }
1074 } else if (name == null) {
1075 name = entry.getName();
1076 } else if (name.equals(entry.getName())) {
1077 resolve = true; // Need to do resolution
1078 }
1079 }
1080 }
1081
1082 // Full Mangle if resolution is necessary.
1083 if (resolve) {
1084 boolean firstType = true;
1085
1086 for (int i = 0; i < v.size(); ++i) {
1087 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
1088
1089 if (entry instanceof Element) {
1090 entry.setName(mangleName(entry.getName(), ELEMENT_SUFFIX));
1091
1092 // If this global element was defined using
1093 // an anonymous type, then need to change the
1094 // java name of the anonymous type to match.
1095 QName anonQName =
1096 new QName(entry.getQName().getNamespaceURI(),
1097 SymbolTable.ANON_TOKEN
1098 + entry.getQName().getLocalPart());
1099
1100 TypeEntry anonType =
1101 symbolTable.getType(anonQName);
1102
1103 if (anonType != null) {
1104 anonType.setName(entry.getName());
1105 anonTypes.add(anonType);
1106 }
1107 } else if (entry instanceof TypeEntry) {
1108
1109 // Search all other types for java names that match this one.
1110 // The sameJavaClass method returns true if the java names are
1111 // the same (ignores [] ).
1112 if (firstType) {
1113 firstType = false;
1114
1115 Iterator types =
1116 symbolTable.getTypeIndex().values().iterator();
1117
1118 while (types.hasNext()) {
1119 TypeEntry type = (TypeEntry) types.next();
1120
1121 if ((type != entry)
1122 && (type.getBaseType() == null)
1123 && sameJavaClass(entry.getName(),
1124 type.getName())) {
1125 v.add(type);
1126 }
1127 }
1128 }
1129
1130 // If this is an anonymous type, it's name was resolved in
1131 // the previous if block. Don't reresolve it.
1132 if (!anonTypes.contains(entry)) {
1133 // In case that other entry in name collision among
1134 // PortTypeEntry, ServiceEntry and BindingEntry
1135
1136 boolean needResolve = false;
1137
1138 // check collision of TypeEntry with PortTypeEntry, ServiceEtnry and/or BindingEntry
1139 for (int j = 0; j < v.size(); j++) {
1140 SymTabEntry e = (SymTabEntry) v.elementAt(j);
1141 if ((e instanceof PortTypeEntry
1142 || e instanceof ServiceEntry
1143 || e instanceof BindingEntry)) {
1144 needResolve = true;
1145 break;
1146 }
1147 }
1148
1149 if (!needResolve) {
1150 continue;
1151 }
1152
1153 // Appended Suffix for avoiding name collisions (JAX-RPC 1.1)
1154 Boolean isComplexTypeFault = (Boolean)entry.getDynamicVar(COMPLEX_TYPE_FAULT);
1155 if ((isComplexTypeFault != null) && isComplexTypeFault.booleanValue()) {
1156 entry.setName(mangleName(entry.getName(), EXCEPTION_SUFFIX));
1157 }
1158 else {
1159 entry.setName(mangleName(entry.getName(), TYPE_SUFFIX));
1160 }
1161
1162 // should update the class name of ElementEntry which references this type entry
1163 Map elementIndex = symbolTable.getElementIndex();
1164 List elements = new ArrayList(elementIndex.values());
1165 for (int j = 0; j < elementIndex.size(); j++) {
1166 TypeEntry te = (TypeEntry) elements.get(j);
1167 TypeEntry ref = te.getRefType();
1168 if (ref != null && entry.getQName().equals(ref.getQName())) {
1169 te.setName(entry.getName());
1170 }
1171 }
1172
1173 // Need to resolve a complex-type exception message.
1174 if ((isComplexTypeFault != null) && isComplexTypeFault.booleanValue()) {
1175 // SHOULD update the exception class name of a referencing message entry.
1176 List messageEntries = symbolTable.getMessageEntries();
1177 for (int j = 0; j < messageEntries.size(); j++) {
1178 MessageEntry messageEntry = (MessageEntry)messageEntries.get(j);
1179 Boolean isComplexTypeFaultMsg = (Boolean)messageEntry.getDynamicVar(COMPLEX_TYPE_FAULT);
1180 if ((isComplexTypeFaultMsg != null) && (isComplexTypeFaultMsg.booleanValue())) {
1181 QName exceptionDataType = (QName)messageEntry.getDynamicVar(EXCEPTION_DATA_TYPE);
1182 if (((TypeEntry)entry).getQName().equals(exceptionDataType)) {
1183 String className = (String)messageEntry.getDynamicVar(EXCEPTION_CLASS_NAME);
1184 messageEntry.setDynamicVar(EXCEPTION_CLASS_NAME, className + EXCEPTION_SUFFIX);
1185 }
1186 }
1187 }
1188 }
1189 }
1190 } else if (entry instanceof PortTypeEntry) {
1191 entry.setName(mangleName(entry.getName(), PORT_TYPE_SUFFIX)); // "_Port" --> "_PortType" for JAX-RPC 1.1
1192 } else if (entry instanceof ServiceEntry) {
1193 entry.setName(mangleName(entry.getName(), SERVICE_SUFFIX));
1194 } else if (entry instanceof MessageEntry) {
1195 Boolean complexTypeFault =
1196 (Boolean) entry.getDynamicVar(COMPLEX_TYPE_FAULT);
1197 if ((complexTypeFault == null) || !complexTypeFault.booleanValue()) {
1198 String exceptionClassName = (String) entry.getDynamicVar(EXCEPTION_CLASS_NAME);
1199 entry.setDynamicVar(EXCEPTION_CLASS_NAME, exceptionClassName + EXCEPTION_SUFFIX);
1200 }
1201 }
1202 // else if (entry instanceof MessageEntry) {
1203 // we don't care about messages
1204 // }
1205 else if (entry instanceof BindingEntry) {
1206 BindingEntry bEntry = (BindingEntry) entry;
1207
1208 // If there is no literal use, then we never see a
1209 // class named directly from the binding name. They
1210 // all have suffixes: Stub, Skeleton, Impl.
1211 // If there IS literal use, then the SDI will be
1212 // named after the binding name, so there is the
1213 // possibility of a name clash.
1214 if (bEntry.hasLiteral()) {
1215 entry.setName(mangleName(entry.getName(),
1216 BINDING_SUFFIX));
1217 }
1218 }
1219 }
1220 }
1221 }
1222 }
1223 } // resolveNameClashes
1224
1225 /**
1226 * Change the indicated type name into a mangled form using the mangle string.
1227 *
1228 * @param name
1229 * @param mangle
1230 * @return
1231 */
1232 private String mangleName(String name, String mangle) {
1233
1234 int index = name.indexOf("[");
1235
1236 if (index >= 0) {
1237 String pre = name.substring(0, index);
1238 String post = name.substring(index);
1239
1240 return pre + mangle + post;
1241 } else {
1242 return name + mangle;
1243 }
1244 }
1245
1246 /**
1247 * Returns true if same java class, ignore []
1248 *
1249 * @param one
1250 * @param two
1251 * @return
1252 */
1253 private boolean sameJavaClass(String one, String two) {
1254
1255 int index1 = one.indexOf("[");
1256 int index2 = two.indexOf("[");
1257
1258 if (index1 > 0) {
1259 one = one.substring(0, index1);
1260 }
1261
1262 if (index2 > 0) {
1263 two = two.substring(0, index2);
1264 }
1265
1266 return one.equals(two);
1267 }
1268
1269 /**
1270 * The --all flag is set on the command line (or generateAll(true) is called
1271 * on WSDL2Java). Set all symbols as referenced (except nonSOAP bindings
1272 * which we don't know how to deal with).
1273 */
1274 protected void setAllReferencesToTrue() {
1275
1276 Iterator it = symbolTable.getHashMap().values().iterator();
1277
1278 while (it.hasNext()) {
1279 Vector v = (Vector) it.next();
1280
1281 for (int i = 0; i < v.size(); ++i) {
1282 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
1283
1284 if ((entry instanceof BindingEntry)
1285 && ((BindingEntry) entry).getBindingType()
1286 != BindingEntry.TYPE_SOAP) {
1287 entry.setIsReferenced(false);
1288 } else {
1289 entry.setIsReferenced(true);
1290 }
1291 }
1292 }
1293 } // setAllReferencesToTrue
1294
1295 /**
1296 * If a binding's type is not TYPE_SOAP, then we don't use that binding
1297 * or that binding's portType.
1298 *
1299 * @param symbolTable
1300 */
1301 protected void ignoreNonSOAPBindings(SymbolTable symbolTable) {
1302
1303 // Look at all uses of the portTypes. If none of the portType's bindings are of type
1304 // TYPE_SOAP, then turn off that portType's isReferenced flag.
1305 Vector unusedPortTypes = new Vector();
1306 Vector usedPortTypes = new Vector();
1307 Iterator it = symbolTable.getHashMap().values().iterator();
1308
1309 while (it.hasNext()) {
1310 Vector v = (Vector) it.next();
1311
1312 for (int i = 0; i < v.size(); ++i) {
1313 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
1314
1315 if (entry instanceof BindingEntry) {
1316 BindingEntry bEntry = (BindingEntry) entry;
1317 Binding binding = bEntry.getBinding();
1318 PortType portType = binding.getPortType();
1319 PortTypeEntry ptEntry =
1320 symbolTable.getPortTypeEntry(portType.getQName());
1321
1322 if (bEntry.getBindingType() == BindingEntry.TYPE_SOAP) {
1323
1324 // If a binding is of type TYPE_SOAP, then mark its portType used
1325 // (ie., add it to the usedPortTypes list. If the portType was
1326 // previously marked as unused, unmark it (in other words, remove it
1327 // from the unusedPortTypes list).
1328 usedPortTypes.add(ptEntry);
1329
1330 if (unusedPortTypes.contains(ptEntry)) {
1331 unusedPortTypes.remove(ptEntry);
1332 }
1333 } else {
1334 bEntry.setIsReferenced(false);
1335
1336 // If a binding is not of type TYPE_SOAP, then mark its portType as
1337 // unused ONLY if it hasn't already been marked as used.
1338 if (!usedPortTypes.contains(ptEntry)) {
1339 unusedPortTypes.add(ptEntry);
1340 }
1341 }
1342 }
1343 }
1344 }
1345
1346 // Go through all the portTypes that are marked as unused and set their isReferenced flags
1347 // to false.
1348 for (int i = 0; i < unusedPortTypes.size(); ++i) {
1349 PortTypeEntry ptEntry = (PortTypeEntry) unusedPortTypes.get(i);
1350
1351 ptEntry.setIsReferenced(false);
1352 }
1353 } // ignoreNonSOAPBindings
1354
1355 /**
1356 * Method constructSignatures
1357 *
1358 * @param symbolTable
1359 */
1360 protected void constructSignatures(SymbolTable symbolTable) {
1361
1362 Iterator it = symbolTable.getHashMap().values().iterator();
1363
1364 while (it.hasNext()) {
1365 Vector v = (Vector) it.next();
1366
1367 for (int i = 0; i < v.size(); ++i) {
1368 SymTabEntry entry = (SymTabEntry) v.elementAt(i);
1369
1370 if (entry instanceof BindingEntry) {
1371 BindingEntry bEntry = (BindingEntry) entry;
1372 Binding binding = bEntry.getBinding();
1373 PortTypeEntry ptEntry = symbolTable.getPortTypeEntry(
1374 binding.getPortType().getQName());
1375 PortType portType = ptEntry.getPortType();
1376 Iterator operations =
1377 portType.getOperations().iterator();
1378
1379 while (operations.hasNext()) {
1380 Operation operation =
1381 (Operation) operations.next();
1382 String wsdlOpName = operation.getName();
1383 OperationType type = operation.getStyle();
1384
1385 String javaOpName = getOperationJavaNameHook(bEntry, wsdlOpName); // for derived class
1386 if (javaOpName == null) {
1387 javaOpName = operation.getName();
1388 }
1389
1390 Parameters parameters =
1391 bEntry.getParameters(operation);
1392
1393 if (OperationType.SOLICIT_RESPONSE.equals(type)) {
1394 parameters.signature =
1395 " // "
1396 + Messages.getMessage("invalidSolResp00", javaOpName);
1397
1398 System.err.println(
1399 Messages.getMessage("invalidSolResp00", javaOpName));
1400 } else if (OperationType.NOTIFICATION.equals(type)) {
1401 parameters.signature =
1402 " // "
1403 + Messages.getMessage("invalidNotif00", javaOpName);
1404
1405 System.err.println(
1406 Messages.getMessage("invalidNotif00", javaOpName));
1407 } else { // ONE_WAY or REQUEST_RESPONSE
1408 if (parameters != null) {
1409 String returnType = getReturnTypeJavaNameHook(bEntry, wsdlOpName);
1410 if (returnType != null) {
1411 if (parameters.returnParam != null) { // 'void' return type???
1412 parameters.returnParam.getType().setName(returnType);
1413 }
1414 }
1415 for (int j = 0; j < parameters.list.size(); ++j) {
1416 Parameter p = (Parameter) parameters.list.get(j);
1417 String paramType = getParameterTypeJavaNameHook(bEntry, wsdlOpName, j);
1418 if (paramType != null) {
1419 p.getType().setName(paramType);
1420 }
1421 }
1422 parameters.signature =
1423 constructSignature(parameters, javaOpName);
1424 }
1425 }
1426 }
1427 }
1428 }
1429 }
1430 } // constructSignatures
1431
1432 protected String getOperationJavaNameHook(BindingEntry bEntry, String wsdlOpName) {
1433 return null;
1434 }
1435
1436 protected String getReturnTypeJavaNameHook(BindingEntry bEntry, String wsdlOpName) {
1437 return null;
1438 }
1439
1440 protected String getParameterTypeJavaNameHook(BindingEntry bEntry, String wsdlOpName, int pos) {
1441 return null;
1442 }
1443
1444 /**
1445 * Construct the signature, which is used by both the interface and the stub.
1446 *
1447 * @param parms
1448 * @param opName
1449 * @return
1450 */
1451 private String constructSignature(Parameters parms, String opName) {
1452
1453 String name = Utils.xmlNameToJava(opName);
1454 String ret = "void";
1455
1456 if ((parms != null) && (parms.returnParam != null)) {
1457 ret = Utils.getParameterTypeName(parms.returnParam);
1458 }
1459
1460 String signature = " public " + ret + " " + name + "(";
1461 boolean needComma = false;
1462
1463 for (int i = 0; (parms != null) && (i < parms.list.size()); ++i) {
1464 Parameter p = (Parameter) parms.list.get(i);
1465
1466 if (needComma) {
1467 signature = signature + ", ";
1468 } else {
1469 needComma = true;
1470 }
1471
1472 String javifiedName = Utils.xmlNameToJava(p.getName());
1473
1474 if (p.getMode() == Parameter.IN) {
1475 signature += Utils.getParameterTypeName(p) + " " + javifiedName;
1476 } else {
1477 signature += Utils.holder(p, emitter) + " " + javifiedName;
1478 }
1479 }
1480
1481 signature = signature + ") throws java.rmi.RemoteException";
1482
1483 if ((parms != null) && (parms.faults != null)) {
1484
1485 // Collect the list of faults into a single string, separated by commas.
1486 Iterator i = parms.faults.values().iterator();
1487
1488 while (i.hasNext()) {
1489 Fault fault = (Fault) i.next();
1490 String exceptionName =
1491 Utils.getFullExceptionName(fault.getMessage(), symbolTable);
1492
1493 if (exceptionName != null) {
1494 signature = signature + ", " + exceptionName;
1495 }
1496 }
1497 }
1498
1499 return signature;
1500 } // constructSignature
1501
1502 /**
1503 * Find all inout/out parameters and add a flag to the Type of that parameter saying a holder
1504 * is needed.
1505 *
1506 * @param symbolTable
1507 */
1508 protected void determineIfHoldersNeeded(SymbolTable symbolTable) {
1509
1510 Iterator it = symbolTable.getHashMap().values().iterator();
1511
1512 while (it.hasNext()) {
1513 Vector v = (Vector) it.next();
1514
1515 for (int i = 0; i < v.size(); ++i) {
1516 if (v.get(i) instanceof BindingEntry) {
1517
1518 // If entry is a BindingEntry, look at all the Parameters
1519 // in its portType
1520 BindingEntry bEntry = (BindingEntry) v.get(i);
1521
1522 // PortTypeEntry ptEntry =
1523 // symbolTable.getPortTypeEntry(bEntry.getBinding().getPortType().getQName());
1524 Iterator operations =
1525 bEntry.getParameters().values().iterator();
1526
1527 while (operations.hasNext()) {
1528 Parameters parms = (Parameters) operations.next();
1529
1530 for (int j = 0; j < parms.list.size(); ++j) {
1531 Parameter p = (Parameter) parms.list.get(j);
1532
1533 // If the given parameter is an inout or out parameter, then
1534 // set a HOLDER_IS_NEEDED flag using the dynamicVar design.
1535 if (p.getMode() != Parameter.IN) {
1536 TypeEntry typeEntry = p.getType();
1537
1538 typeEntry.setDynamicVar(
1539 JavaTypeWriter.HOLDER_IS_NEEDED,
1540 Boolean.TRUE);
1541
1542 // If this is a complex then set the HOLDER_IS_NEEDED
1543 // for the reftype too.
1544 if (!typeEntry.isSimpleType()
1545 && (typeEntry.getRefType() != null)) {
1546 typeEntry.getRefType().setDynamicVar(
1547 JavaTypeWriter.HOLDER_IS_NEEDED,
1548 Boolean.TRUE);
1549 }
1550
1551 // If the type is a DefinedElement, need to
1552 // set HOLDER_IS_NEEDED on the anonymous type.
1553 QName anonQName =
1554 SchemaUtils.getElementAnonQName(
1555 p.getType().getNode());
1556
1557 if (anonQName != null) {
1558 TypeEntry anonType =
1559 symbolTable.getType(anonQName);
1560
1561 if (anonType != null) {
1562 anonType.setDynamicVar(
1563 JavaTypeWriter.HOLDER_IS_NEEDED,
1564 Boolean.TRUE);
1565 }
1566 }
1567 }
1568 }
1569 }
1570 }
1571 }
1572 }
1573 } // determineIfHoldersNeeded
1574
1575 /**
1576 * Get TypeMapping to use for translating
1577 * QNames to java base types
1578 */
1579 BaseTypeMapping btm = null;
1580
1581 /**
1582 * Method setBaseTypeMapping
1583 *
1584 * @param btm
1585 */
1586 public void setBaseTypeMapping(BaseTypeMapping btm) {
1587 this.btm = btm;
1588 }
1589
1590 /**
1591 * Method getBaseTypeMapping
1592 *
1593 * @return
1594 */
1595 public BaseTypeMapping getBaseTypeMapping() {
1596 if (btm == null) {
1597 btm = new BaseTypeMapping() {
1598
1599 public String getBaseName(QName qNameIn) {
1600
1601 javax.xml.namespace.QName qName =
1602 new javax.xml.namespace.QName(qNameIn.getNamespaceURI(),
1603 qNameIn.getLocalPart());
1604 Class cls =
1605 emitter.getDefaultTypeMapping().getClassForQName(qName);
1606
1607 if (cls == null) {
1608 return null;
1609 } else {
1610 return JavaUtils.getTextClassName(cls.getName());
1611 }
1612 }
1613 };
1614 }
1615
1616 return btm;
1617 }
1618
1619 /**
1620 * Determines whether the QName supplied should be generated by comparing
1621 * the namespace for the QName against the included and excluded names.
1622 <p/>
1623 <ul>
1624 <li>if both the includes and excludes are both empty,
1625 the element is generated</li>
1626 <li>if the namespace is in the includes,
1627 the element is generated</li>
1628 <li>if the namespace is not in the excludes and the includes are empty,
1629 the element will be generated.
1630 <li>if the namespace is only in the excludes,
1631 the element is not generated</li>
1632 <li>if the namespace is not in the includes and the includes are not
1633 empty, the element is not generated</li>
1634 @param qName
1635 @return
1636 */
1637 protected boolean include(QName qName) {
1638 String namespace =
1639 (qName != null && qName.getNamespaceURI() != null)
1640 ? qName.getNamespaceURI()
1641 : "";
1642
1643 boolean doInclude = false;
1644 NamespaceSelector selector = new NamespaceSelector(namespace);
1645 if (qName == null
1646 || emitter == null
1647 || emitter.getNamespaceIncludes().contains(selector)
1648 || (emitter.getNamespaceIncludes().size() == 0
1649 && !emitter.getNamespaceExcludes().contains(selector))) {
1650 doInclude = true;
1651 }
1652 else {
1653 log_.info(
1654 "excluding code generation for non-included QName:" + qName);
1655
1656 }
1657 return doInclude;
1658 }
1659
1660} // class JavaGeneratorFactory