| /* |
| * Copyright 2001-2004 The Apache Software Foundation. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.axis.wsdl.toJava; |
| |
| import org.apache.axis.components.logger.LogFactory; |
| import org.apache.axis.utils.JavaUtils; |
| import org.apache.axis.utils.Messages; |
| import org.apache.axis.wsdl.gen.Generator; |
| import org.apache.axis.wsdl.gen.GeneratorFactory; |
| import org.apache.axis.wsdl.gen.NoopGenerator; |
| import org.apache.axis.wsdl.symbolTable.BaseTypeMapping; |
| import org.apache.axis.wsdl.symbolTable.BindingEntry; |
| import org.apache.axis.wsdl.symbolTable.ContainedAttribute; |
| import org.apache.axis.wsdl.symbolTable.Element; |
| import org.apache.axis.wsdl.symbolTable.ElementDecl; |
| import org.apache.axis.wsdl.symbolTable.FaultInfo; |
| import org.apache.axis.wsdl.symbolTable.MessageEntry; |
| import org.apache.axis.wsdl.symbolTable.Parameter; |
| import org.apache.axis.wsdl.symbolTable.Parameters; |
| import org.apache.axis.wsdl.symbolTable.PortTypeEntry; |
| import org.apache.axis.wsdl.symbolTable.SchemaUtils; |
| import org.apache.axis.wsdl.symbolTable.ServiceEntry; |
| import org.apache.axis.wsdl.symbolTable.SymTabEntry; |
| import org.apache.axis.wsdl.symbolTable.SymbolTable; |
| import org.apache.axis.wsdl.symbolTable.Type; |
| import org.apache.axis.wsdl.symbolTable.TypeEntry; |
| import org.apache.commons.logging.Log; |
| |
| import javax.wsdl.Binding; |
| import javax.wsdl.Definition; |
| import javax.wsdl.Fault; |
| import javax.wsdl.Message; |
| import javax.wsdl.Operation; |
| import javax.wsdl.OperationType; |
| import javax.wsdl.Port; |
| import javax.wsdl.PortType; |
| import javax.wsdl.Service; |
| import javax.xml.namespace.QName; |
| import javax.xml.rpc.holders.BooleanHolder; |
| import java.io.IOException; |
| import java.lang.reflect.Constructor; |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Vector; |
| |
| /** |
| * This is Wsdl2java's implementation of the GeneratorFactory |
| */ |
| public class JavaGeneratorFactory implements GeneratorFactory { |
| private static final Log log = |
| LogFactory.getLog(JavaGeneratorFactory.class.getName()); |
| |
| /** Field emitter */ |
| protected Emitter emitter; |
| |
| /** Field symbolTable */ |
| protected SymbolTable symbolTable; |
| |
| /** Field COMPLEX_TYPE_FAULT */ |
| public static String COMPLEX_TYPE_FAULT = "ComplexTypeFault"; |
| |
| /** Field EXCEPTION_CLASS_NAME */ |
| public static String EXCEPTION_CLASS_NAME = "ExceptionClassName"; |
| |
| /** Field EXCEPTION_DATA_TYPE */ |
| public static String EXCEPTION_DATA_TYPE = "ExceptionDataType"; |
| |
| /* Name suffixes for collision */ |
| private static final String SERVICE_SUFFIX = "_Service"; |
| private static final String PORT_TYPE_SUFFIX = "_PortType"; // "_Port" (Axis classic) --> "_PortType" (JAX-RPC 1.1) |
| private static final String TYPE_SUFFIX = "_Type"; |
| private static final String ELEMENT_SUFFIX = "_Element"; // "_ElemType (Axis classic) --> "_Element" (JAX-RPC 1.1) |
| private static final String EXCEPTION_SUFFIX = "_Exception"; |
| private static final String BINDING_SUFFIX = "_Binding"; |
| |
| |
| /** |
| * Default constructor. Note that this class is unusable until setEmitter |
| * is called. |
| */ |
| public JavaGeneratorFactory() { |
| addGenerators(); |
| } // ctor |
| |
| /** |
| * Constructor JavaGeneratorFactory |
| * |
| * @param emitter |
| */ |
| public JavaGeneratorFactory(Emitter emitter) { |
| |
| this.emitter = emitter; |
| |
| addGenerators(); |
| } // ctor |
| |
| /** |
| * Method setEmitter |
| * |
| * @param emitter |
| */ |
| public void setEmitter(Emitter emitter) { |
| this.emitter = emitter; |
| } // setEmitter |
| |
| /** |
| * Method addGenerators |
| */ |
| private void addGenerators() { |
| |
| addMessageGenerators(); |
| addPortTypeGenerators(); |
| addBindingGenerators(); |
| addServiceGenerators(); |
| addTypeGenerators(); |
| addDefinitionGenerators(); |
| } // addGenerators |
| |
| /** |
| * These addXXXGenerators are called by the constructor. |
| * If an extender of this factory wants to CHANGE the set |
| * of generators that are called per WSDL construct, they |
| * should override these addXXXGenerators methods. If all |
| * an extender wants to do is ADD a generator, then the |
| * extension should simply call addGenerator. |
| * (NOTE: It doesn't quite work this way, yet. Only the |
| * Definition generators fit this model at this point in |
| * time.) |
| */ |
| protected void addMessageGenerators() { |
| } // addMessageGenerators |
| |
| /** |
| * Method addPortTypeGenerators |
| */ |
| protected void addPortTypeGenerators() { |
| } // addPortTypeGenerators |
| |
| /** |
| * Method addBindingGenerators |
| */ |
| protected void addBindingGenerators() { |
| } // addBindingGenerators |
| |
| /** |
| * Method addServiceGenerators |
| */ |
| protected void addServiceGenerators() { |
| } // addServiceGenerators |
| |
| /** |
| * Method addTypeGenerators |
| */ |
| protected void addTypeGenerators() { |
| } // addTypeGenerators |
| |
| /** |
| * Method addDefinitionGenerators |
| */ |
| protected void addDefinitionGenerators() { |
| |
| addGenerator(Definition.class, JavaDefinitionWriter.class); // for faults |
| addGenerator(Definition.class, |
| JavaDeployWriter.class); // for deploy.wsdd |
| addGenerator(Definition.class, |
| JavaUndeployWriter.class); // for undeploy.wsdd |
| addGenerator(Definition.class, |
| JavaBuildFileWriter.class); //add a build file writer |
| |
| } // addDefinitionGenerators |
| |
| |
| /** |
| * Do the Wsdl2java generator pass: |
| * - resolve name clashes |
| * - construct signatures |
| * |
| * @param def |
| * @param symbolTable |
| */ |
| public void generatorPass(Definition def, SymbolTable symbolTable) { |
| |
| this.symbolTable = symbolTable; |
| |
| javifyNames(symbolTable); |
| setFaultContext(symbolTable); |
| resolveNameClashes(symbolTable); |
| determineInterfaceNames(symbolTable); |
| |
| if (emitter.isAllWanted()) { |
| setAllReferencesToTrue(); |
| } else { |
| ignoreNonSOAPBindings(symbolTable); |
| } |
| |
| constructSignatures(symbolTable); |
| determineIfHoldersNeeded(symbolTable); |
| } // generatorPass |
| |
| /** Since Wsdl2java doesn't emit anything for Messages, return the No-op generator. */ |
| private Writers messageWriters = new Writers(); |
| |
| /** |
| * Method getGenerator |
| * |
| * @param message |
| * @param symbolTable |
| * @return |
| */ |
| public Generator getGenerator(Message message, SymbolTable symbolTable) { |
| if (include(message.getQName())) { |
| MessageEntry mEntry = symbolTable.getMessageEntry(message.getQName()); |
| messageWriters.addStuff(new NoopGenerator(), mEntry, symbolTable); |
| return messageWriters; |
| } |
| else { |
| return new NoopGenerator(); |
| } |
| } // getGenerator |
| |
| /** Return Wsdl2java's JavaPortTypeWriter object. */ |
| private Writers portTypeWriters = new Writers(); |
| |
| /** |
| * Method getGenerator |
| * |
| * @param portType |
| * @param symbolTable |
| * @return |
| */ |
| public Generator getGenerator(PortType portType, SymbolTable symbolTable) { |
| if (include(portType.getQName())) { |
| PortTypeEntry ptEntry = |
| symbolTable.getPortTypeEntry(portType.getQName()); |
| portTypeWriters.addStuff(new NoopGenerator(), ptEntry, symbolTable); |
| return portTypeWriters; |
| } |
| else { |
| return new NoopGenerator(); |
| } |
| } // getGenerator |
| |
| /** Return Wsdl2java's JavaBindingWriter object. */ |
| protected Writers bindingWriters = new Writers(); |
| |
| /** |
| * Method getGenerator |
| * |
| * @param binding |
| * @param symbolTable |
| * @return |
| */ |
| public Generator getGenerator(Binding binding, SymbolTable symbolTable) { |
| if (include(binding.getQName())) { |
| Generator writer = new JavaBindingWriter(emitter, binding, |
| symbolTable); |
| BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName()); |
| bindingWriters.addStuff(writer, bEntry, symbolTable); |
| return bindingWriters; |
| } |
| else { |
| return new NoopGenerator(); |
| } |
| } // getGenerator |
| |
| /** Return Wsdl2java's JavaServiceWriter object. */ |
| protected Writers serviceWriters = new Writers(); |
| |
| /** |
| * Method getGenerator |
| * |
| * @param service |
| * @param symbolTable |
| * @return |
| */ |
| public Generator getGenerator(Service service, SymbolTable symbolTable) { |
| if (include(service.getQName())) { |
| Generator writer = new JavaServiceWriter(emitter, service, |
| symbolTable); |
| ServiceEntry sEntry = symbolTable.getServiceEntry(service.getQName()); |
| serviceWriters.addStuff(writer, sEntry, symbolTable); |
| return serviceWriters; |
| } |
| else { |
| return new NoopGenerator(); |
| } |
| } // getGenerator |
| |
| /** Return Wsdl2java's JavaTypeWriter object. */ |
| private Writers typeWriters = new Writers(); |
| |
| /** |
| * Method getGenerator |
| * |
| * @param type |
| * @param symbolTable |
| * @return |
| */ |
| public Generator getGenerator(TypeEntry type, SymbolTable symbolTable) { |
| if (include(type.getQName())) { |
| Generator writer = new JavaTypeWriter(emitter, type, symbolTable); |
| typeWriters.addStuff(writer, type, symbolTable); |
| return typeWriters; |
| } |
| else { |
| return new NoopGenerator(); |
| } |
| } // getGenerator |
| |
| /** Return Wsdl2java's JavaDefinitionWriter object. */ |
| private Writers defWriters = new Writers(); |
| |
| /** |
| * Method getGenerator |
| * |
| * @param definition |
| * @param symbolTable |
| * @return |
| */ |
| public Generator getGenerator(Definition definition, |
| SymbolTable symbolTable) { |
| if (include(definition.getQName())) { |
| defWriters.addStuff(null, definition, symbolTable); |
| return defWriters; |
| } |
| else { |
| return new NoopGenerator(); |
| } |
| } // getGenerator |
| |
| // Hack class just to play with the idea of adding writers |
| |
| /** |
| * Class Writers |
| * |
| * @version %I%, %G% |
| */ |
| protected class Writers implements Generator { |
| |
| /** Field writers */ |
| Vector writers = new Vector(); |
| |
| /** Field symbolTable */ |
| SymbolTable symbolTable = null; |
| |
| /** Field baseWriter */ |
| Generator baseWriter = null; |
| |
| // entry or def, but not both, will be a parameter. |
| |
| /** Field entry */ |
| SymTabEntry entry = null; |
| |
| /** Field def */ |
| Definition def = null; |
| |
| /** |
| * Method addGenerator |
| * |
| * @param writer |
| */ |
| public void addGenerator(Class writer) { |
| writers.add(writer); |
| } // addWriter |
| |
| /** |
| * Method addStuff |
| * |
| * @param baseWriter |
| * @param entry |
| * @param symbolTable |
| */ |
| public void addStuff(Generator baseWriter, SymTabEntry entry, |
| SymbolTable symbolTable) { |
| |
| this.baseWriter = baseWriter; |
| this.entry = entry; |
| this.symbolTable = symbolTable; |
| } // addStuff |
| |
| /** |
| * Method addStuff |
| * |
| * @param baseWriter |
| * @param def |
| * @param symbolTable |
| */ |
| public void addStuff(Generator baseWriter, Definition def, |
| SymbolTable symbolTable) { |
| |
| this.baseWriter = baseWriter; |
| this.def = def; |
| this.symbolTable = symbolTable; |
| } // addStuff |
| |
| /** |
| * Method generate |
| * |
| * @throws IOException |
| */ |
| public void generate() throws IOException { |
| |
| if (baseWriter != null) { |
| baseWriter.generate(); |
| } |
| |
| Class[] formalArgs; |
| Object[] actualArgs; |
| |
| if (entry != null) { |
| formalArgs = new Class[]{Emitter.class, entry.getClass(), |
| SymbolTable.class}; |
| actualArgs = new Object[]{emitter, entry, symbolTable}; |
| } else { |
| formalArgs = new Class[]{Emitter.class, Definition.class, |
| SymbolTable.class}; |
| actualArgs = new Object[]{emitter, def, symbolTable}; |
| } |
| |
| for (int i = 0; i < writers.size(); ++i) { |
| Class wClass = (Class) writers.get(i); |
| Generator gen; |
| |
| try { |
| Constructor ctor = wClass.getConstructor(formalArgs); |
| |
| gen = (Generator) ctor.newInstance(actualArgs); |
| } catch (Throwable t) { |
| throw new IOException(Messages.getMessage("exception01", |
| t.getMessage())); |
| } |
| |
| gen.generate(); |
| } |
| } // generate |
| |
| public String toString() { |
| return "Writers[baseWriter=" + baseWriter + ",writers=" + writers + ",entry.name=" + (entry == null ? "N/A" : entry.getName()) + "]"; |
| } |
| } // class Writers |
| |
| /** |
| * Method addGenerator |
| * |
| * @param wsdlClass |
| * @param generator |
| */ |
| public void addGenerator(Class wsdlClass, Class generator) { |
| if (log.isDebugEnabled()) { |
| log.debug("Adding generator for " + wsdlClass.getName() + ": " + generator.getName()); |
| } |
| |
| // This is just a hack right now... it just works with Service |
| if (Message.class.isAssignableFrom(wsdlClass)) { |
| messageWriters.addGenerator(generator); |
| } else if (PortType.class.isAssignableFrom(wsdlClass)) { |
| portTypeWriters.addGenerator(generator); |
| } else if (Binding.class.isAssignableFrom(wsdlClass)) { |
| bindingWriters.addGenerator(generator); |
| } else if (Service.class.isAssignableFrom(wsdlClass)) { |
| serviceWriters.addGenerator(generator); |
| } else if (TypeEntry.class.isAssignableFrom(wsdlClass)) { |
| typeWriters.addGenerator(generator); |
| } else if (Definition.class.isAssignableFrom(wsdlClass)) { |
| defWriters.addGenerator(generator); |
| } |
| } // addGenerator |
| |
| /** |
| * Fill in the names of each SymTabEntry with the javaified name. |
| * Note: This method also ensures that anonymous types are |
| * given unique java type names. |
| * |
| * @param symbolTable |
| */ |
| protected void javifyNames(SymbolTable symbolTable) { |
| |
| int uniqueNum = 0; |
| HashMap anonQNames = new HashMap(); |
| Iterator it = symbolTable.getHashMap().values().iterator(); |
| |
| while (it.hasNext()) { |
| Vector v = (Vector) it.next(); |
| |
| for (int i = 0; i < v.size(); ++i) { |
| SymTabEntry entry = (SymTabEntry) v.elementAt(i); |
| |
| if (entry.getName() != null) { |
| continue; |
| } |
| |
| // Use the type or the referenced type's QName to generate the java name. |
| if (entry instanceof TypeEntry) { |
| uniqueNum = javifyTypeEntryName(symbolTable, (TypeEntry) entry, anonQNames, uniqueNum); |
| } |
| |
| // If it is not a type, then use this entry's QName to |
| // generate its name. |
| else { |
| entry.setName(emitter.getJavaName(entry.getQName())); |
| } |
| } |
| } |
| } // javifyNames |
| |
| /** Refactored to call recursively for JAX-RPC 1.1 spec 4.2.5. */ |
| protected int javifyTypeEntryName(SymbolTable symbolTable, TypeEntry entry, HashMap anonQNames, int uniqueNum) { |
| TypeEntry tEntry = entry; |
| String dims = tEntry.getDimensions(); |
| TypeEntry refType = tEntry.getRefType(); |
| while (refType != null) { |
| tEntry = refType; |
| dims += tEntry.getDimensions(); |
| refType = tEntry.getRefType(); |
| } |
| |
| TypeEntry te = tEntry; |
| while (te != null) { |
| TypeEntry base = SchemaUtils.getBaseType(te, symbolTable); |
| if (base == null) |
| break; |
| |
| uniqueNum = javifyTypeEntryName(symbolTable, base, anonQNames, uniqueNum); |
| |
| if (Utils.getEnumerationBaseAndValues(te.getNode(), symbolTable) == null |
| &&SchemaUtils.getComplexElementExtensionBase(te.getNode(), symbolTable) == null |
| && te.getContainedAttributes() == null) { |
| if(!SchemaUtils.isSimpleTypeWithUnion(te.getNode())) { |
| if (base.isSimpleType()) { |
| // Case 1: |
| // <simpleType name="mySimpleStringType"> |
| // <restriction base="xs:string"> |
| // </restriction> |
| // </simpleType> |
| te.setSimpleType(true); |
| te.setName(base.getName()); |
| te.setRefType(base); |
| } |
| |
| if (base.isBaseType()) { |
| // Case 2: |
| // <simpleType name="FooString"> |
| // <restriction base="foo:mySimpleStringType"> |
| // </restriction> |
| // </simpleType> |
| te.setBaseType(true); |
| te.setName(base.getName()); |
| te.setRefType(base); |
| } |
| } |
| } |
| |
| if (!te.isSimpleType()) |
| break; |
| |
| te = base; |
| } |
| |
| // Need to javify the ref'd TypeEntry if it was not |
| // already processed |
| if (tEntry.getName() == null) { |
| boolean processed = false; // true if the java name is already determined |
| // Get the QName of the ref'd TypeEntry, which |
| // is will be used to javify the name |
| QName typeQName = tEntry.getQName(); |
| |
| // In case of <xsd:list itemType="...">, |
| // set typeQName to the value of the itemType attribute. |
| QName itemType = SchemaUtils.getListItemType(tEntry.getNode()); |
| if (itemType != null) { |
| // Get the typeEntry so we know the absolute base type |
| TypeEntry itemEntry = symbolTable.getTypeEntry(itemType, false); |
| // TODO - If the itemEntry is not found, we need to throw |
| // an exception. "Item is referenced, but not defined" |
| javifyTypeEntryName(symbolTable, itemEntry, anonQNames, uniqueNum); |
| // Grab the referenced type, If it's there. |
| TypeEntry refedEntry = itemEntry.getRefType(); |
| QName baseName = refedEntry == null ? itemEntry.getQName() : |
| refedEntry.getQName(); |
| typeQName = new QName(baseName.getNamespaceURI(), |
| baseName.getLocalPart() + "[]"); |
| } |
| |
| if (emitter.isDeploy()) { |
| Class class1 = (Class) emitter.getQName2ClassMap().get(typeQName); |
| if (class1 != null && !class1.isArray()) { |
| tEntry.setName(getJavaClassName(class1)); |
| processed = true; |
| } |
| } |
| |
| if (!processed) { |
| if ((typeQName.getLocalPart(). |
| indexOf(SymbolTable.ANON_TOKEN) < 0)) { |
| // Normal Case: The ref'd type is not anonymous |
| // Simply construct the java name from |
| // the qName |
| tEntry.setName(emitter.getJavaName(typeQName)); |
| } else { |
| // This is an anonymous type name. |
| // Axis uses '>' as a nesting token to generate |
| // unique qnames for anonymous types. |
| // Only consider the localName after the last '>' |
| // when generating the java name |
| // String localName = typeQName.getLocalPart(); |
| // localName = |
| // localName.substring( |
| // localName.lastIndexOf( |
| // SymbolTable.ANON_TOKEN)+1); |
| // typeQName = new QName(typeQName.getNamespaceURI(), |
| // localName); |
| String localName = typeQName.getLocalPart(); |
| |
| // Check to see if this is an anonymous type, |
| // if it is, replace Axis' ANON_TOKEN with |
| // an underscore to make sure we don't run |
| // into name collisions with similarly named |
| // non-anonymous types |
| StringBuffer sb = new StringBuffer(localName); |
| int aidx; |
| |
| while ((aidx = sb.toString().indexOf(SymbolTable.ANON_TOKEN)) > -1) { |
| sb.replace(aidx, aidx + SymbolTable.ANON_TOKEN.length(), ""); |
| char c = sb.charAt(aidx); |
| if (Character.isLetter(c) && Character.isLowerCase(c)) { |
| sb.setCharAt(aidx, Character.toUpperCase(c)); |
| } |
| } |
| |
| localName = sb.toString(); |
| typeQName = new QName(typeQName.getNamespaceURI(), |
| localName); |
| |
| if (emitter.isTypeCollisionProtection() && |
| !emitter.getNamespaceExcludes().contains(new NamespaceSelector(typeQName.getNamespaceURI()))) { |
| // If there is already an existing type, |
| // there will be a collision. |
| // If there is an existing anon type, |
| // there will be a collision. |
| // In both cases, mangle the name. |
| if (symbolTable.getType(typeQName) != null || |
| anonQNames.get(typeQName) != null) { |
| localName += "Type" + uniqueNum++; |
| typeQName = |
| new QName(typeQName.getNamespaceURI(), |
| localName); |
| } |
| |
| anonQNames.put(typeQName, typeQName); |
| } |
| |
| // Now set the name with the constructed qname |
| tEntry.setName(emitter.getJavaName(typeQName)); |
| } |
| } // if (!processed) |
| |
| Vector elements = tEntry.getContainedElements(); |
| if (elements != null) { |
| for (int i = 0; i < elements.size(); i++) { |
| ElementDecl elem = (ElementDecl) elements.get(i); |
| String varName = emitter.getJavaVariableName(typeQName, elem.getQName(), true); |
| elem.setName(varName); |
| } |
| } |
| |
| Vector attributes = tEntry.getContainedAttributes(); |
| if (attributes != null) { |
| for (int i = 0; i < attributes.size(); i++) { |
| ContainedAttribute attr = (ContainedAttribute) attributes.get(i); |
| String varName = emitter.getJavaVariableName(typeQName, attr.getQName(), false); |
| attr.setName(varName); |
| } |
| } |
| } |
| |
| // Set the entry with the same name as the ref'd entry |
| // but add the appropriate amount of dimensions |
| entry.setName(tEntry.getName() + dims); |
| |
| return uniqueNum; |
| } |
| |
| /** |
| * Gets class name from Java class. |
| * If the class is an array, get its component type's name |
| * @param clazz a java class |
| * @return the class name in string |
| */ |
| private static String getJavaClassName(Class clazz) { |
| Class class1 = clazz; |
| |
| while (class1.isArray()) { |
| class1 = class1.getComponentType(); |
| } |
| |
| String name = class1.getName(); |
| name.replace('$', '.'); |
| return name; |
| } |
| |
| /** |
| * setFaultContext: |
| * Processes the symbol table and sets the COMPLEX_TYPE_FAULT |
| * on each TypeEntry that is a complexType and is referenced in |
| * a fault message. TypeEntries that are the base or derived |
| * from such a TypeEntry are also marked with COMPLEX_TYPE_FAULT. |
| * The containing MessageEntry is marked with cOMPLEX_TYPE_FAULT, and |
| * all MessageEntries for faults are tagged with the |
| * EXCEPTION_CLASS_NAME variable, which indicates the java exception |
| * class name. |
| * |
| * @param symbolTable SymbolTable |
| */ |
| private void setFaultContext(SymbolTable symbolTable) { |
| |
| Iterator it = symbolTable.getHashMap().values().iterator(); |
| |
| while (it.hasNext()) { |
| Vector v = (Vector) it.next(); |
| |
| for (int i = 0; i < v.size(); ++i) { |
| SymTabEntry entry = (SymTabEntry) v.elementAt(i); |
| |
| // Inspect each BindingEntry in the Symbol Table |
| if (entry instanceof BindingEntry) { |
| BindingEntry bEntry = (BindingEntry) entry; |
| HashMap allOpFaults = bEntry.getFaults(); |
| Iterator ops = allOpFaults.values().iterator(); |
| |
| // set the context for all faults for this binding. |
| while (ops.hasNext()) { |
| ArrayList faults = (ArrayList) ops.next(); |
| |
| for (int j = 0; j < faults.size(); ++j) { |
| FaultInfo info = (FaultInfo) faults.get(j); |
| |
| setFaultContext(info, symbolTable); |
| } |
| } |
| } |
| } |
| } |
| } // setFaultContext |
| |
| /** |
| * setFaultContext: |
| * Helper routine for the setFaultContext method above. |
| * Examines the indicated fault and sets COMPLEX_TYPE_FAULT |
| * EXCEPTION_DATA_TYPE and EXCEPTION_CLASS_NAME as appropriate. |
| * |
| * @param fault FaultInfo to analyze |
| * @param symbolTable SymbolTable |
| */ |
| private void setFaultContext(FaultInfo fault, SymbolTable symbolTable) { |
| |
| QName faultXmlType = null; |
| Vector parts = new Vector(); |
| |
| // Get the parts of the fault's message. |
| // An IOException is thrown if the parts cannot be |
| // processed. Skip such parts for this analysis |
| try { |
| symbolTable.getParametersFromParts( |
| parts, fault.getMessage().getOrderedParts(null), false, |
| fault.getName(), null); |
| } catch (IOException e) { |
| } |
| |
| // Inspect each TypeEntry referenced in a Fault Message Part |
| String exceptionClassName = null; |
| |
| for (int j = 0; j < parts.size(); j++) { |
| TypeEntry te = ((Parameter) (parts.elementAt(j))).getType(); |
| |
| // If the TypeEntry is an element, advance to the type. |
| // This occurs if the message part uses the element= attribute |
| TypeEntry elementTE = null; |
| |
| if (te instanceof Element) { |
| elementTE = te; |
| te = te.getRefType(); |
| } |
| |
| // remember the QName of the type. |
| faultXmlType = te.getQName(); |
| |
| // Determine if the te should be processed using the |
| // simple type mapping or the complex type mapping |
| // NOTE: treat array types as simple types |
| if ((te.getBaseType() != null) || te.isSimpleType() |
| || ((te.getDimensions().length() > 0) |
| && (te.getRefType().getBaseType() != null))) { |
| |
| // Simple Type Exception |
| } else { |
| |
| // Complex Type Exception |
| if (!Utils.isFaultComplex(te)) { |
| |
| // Mark the type as a complex type fault |
| te.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT, |
| Boolean.TRUE); |
| |
| if (elementTE != null) { |
| te.setDynamicVar( |
| JavaGeneratorFactory.COMPLEX_TYPE_FAULT, |
| Boolean.TRUE); |
| } |
| |
| // Mark all derived types as Complex Faults |
| HashSet derivedSet = |
| org.apache.axis.wsdl.symbolTable.Utils.getDerivedTypes( |
| te, symbolTable); |
| Iterator derivedI = derivedSet.iterator(); |
| |
| while (derivedI.hasNext()) { |
| TypeEntry derivedTE = (TypeEntry) derivedI.next(); |
| |
| derivedTE.setDynamicVar( |
| JavaGeneratorFactory.COMPLEX_TYPE_FAULT, |
| Boolean.TRUE); |
| } |
| |
| // Mark all base types as Complex Faults |
| TypeEntry base = |
| SchemaUtils.getComplexElementExtensionBase(te.getNode(), |
| symbolTable); |
| |
| while (base != null) { |
| base.setDynamicVar( |
| JavaGeneratorFactory.COMPLEX_TYPE_FAULT, |
| Boolean.TRUE); |
| |
| base = SchemaUtils.getComplexElementExtensionBase( |
| base.getNode(), symbolTable); |
| } |
| } |
| |
| // The exception class name is the name of the type |
| exceptionClassName = te.getName(); |
| } |
| } |
| |
| String excName = getExceptionJavaNameHook(fault.getMessage().getQName()); // for derived class |
| if (excName != null) { |
| exceptionClassName = excName; |
| } |
| |
| // Set the name of the exception and |
| // whether the exception is a complex type |
| MessageEntry me = |
| symbolTable.getMessageEntry(fault.getMessage().getQName()); |
| |
| if (me != null) { |
| me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_DATA_TYPE, |
| faultXmlType); |
| |
| if (exceptionClassName != null) { |
| me.setDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT, |
| Boolean.TRUE); |
| me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME, |
| exceptionClassName); |
| } else { |
| me.setDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME, |
| emitter.getJavaName(me.getQName())); |
| } |
| } |
| } |
| |
| protected String getExceptionJavaNameHook(QName qname) { |
| return null; |
| } |
| |
| /** |
| * Method determineInterfaceNames |
| * |
| * @param symbolTable |
| */ |
| protected void determineInterfaceNames(SymbolTable symbolTable) { |
| |
| Iterator it = symbolTable.getHashMap().values().iterator(); |
| |
| while (it.hasNext()) { |
| Vector v = (Vector) it.next(); |
| |
| for (int i = 0; i < v.size(); ++i) { |
| SymTabEntry entry = (SymTabEntry) v.elementAt(i); |
| |
| if (entry instanceof BindingEntry) { |
| |
| // The SEI (Service Endpoint Interface) name |
| // is always the portType name. |
| BindingEntry bEntry = (BindingEntry) entry; |
| PortTypeEntry ptEntry = symbolTable.getPortTypeEntry( |
| bEntry.getBinding().getPortType().getQName()); |
| |
| String seiName = getServiceEndpointInterfaceJavaNameHook(ptEntry, bEntry); |
| if (seiName == null) { |
| seiName = ptEntry.getName(); |
| } |
| |
| bEntry.setDynamicVar(JavaBindingWriter.INTERFACE_NAME, |
| seiName); |
| } else if (entry instanceof ServiceEntry) { |
| ServiceEntry sEntry = (ServiceEntry) entry; |
| String siName = getServiceInterfaceJavaNameHook(sEntry); // for derived class |
| if (siName != null) { |
| sEntry.setName(siName); |
| } |
| |
| Service service = sEntry.getService(); |
| Map portMap = service.getPorts(); |
| Iterator portIterator = portMap.values().iterator(); |
| |
| while (portIterator.hasNext()) { |
| Port p = (Port) portIterator.next(); |
| |
| Binding binding = p.getBinding(); |
| BindingEntry bEntry = |
| symbolTable.getBindingEntry(binding.getQName()); |
| |
| // If this isn't a SOAP binding, skip it |
| if (bEntry.getBindingType() != BindingEntry.TYPE_SOAP) { |
| continue; |
| } |
| |
| String portName = getPortJavaNameHook(p.getName()); // for derived class |
| if (portName != null) { |
| bEntry.setDynamicVar(JavaServiceWriter.PORT_NAME + ":" + p.getName(), |
| portName); |
| } |
| } |
| } |
| } |
| } |
| } // determineInterfaceNames |
| |
| protected String getServiceEndpointInterfaceJavaNameHook(PortTypeEntry ptEntry, BindingEntry bEntry) { |
| return null; |
| } |
| |
| protected String getServiceInterfaceJavaNameHook(ServiceEntry sEntry) { |
| return null; |
| } |
| |
| protected String getPortJavaNameHook(String portName) { |
| return null; |
| } |
| |
| /** |
| * Messages, PortTypes, Bindings, and Services can share the same name. If they do in this |
| * Definition, force their names to be suffixed with _PortType and _Service, respectively. |
| * |
| * @param symbolTable |
| */ |
| protected void resolveNameClashes(SymbolTable symbolTable) { |
| |
| // Keep a list of anonymous types so we don't try to resolve them twice. |
| HashSet anonTypes = new HashSet(); |
| List collisionCandidates = new ArrayList(); // List of vector of SymbolTable entry |
| |
| List localParts = new ArrayList(); // all localparts in all symboltable entries |
| for (Iterator i = symbolTable.getHashMap().keySet().iterator(); i.hasNext(); ) { |
| QName qName = (QName)i.next(); |
| String localPart = qName.getLocalPart(); |
| if (!localParts.contains(localPart)) |
| localParts.add(localPart); |
| } |
| |
| Map pkg2NamespacesMap = emitter.getNamespaces().getPkg2NamespacesMap(); |
| for (Iterator i = pkg2NamespacesMap.values().iterator(); i.hasNext(); ) { |
| Vector namespaces = (Vector)i.next(); // namepaces mapped to same package |
| |
| // Combine entry vectors, which have the same entry name, into a new entry vector. |
| for (int j = 0; j < localParts.size(); j++) { |
| Vector v = new Vector(); |
| for (int k = 0; k < namespaces.size(); k++) { |
| QName qName = new QName((String)namespaces.get(k), (String)localParts.get(j)); |
| if (symbolTable.getHashMap().get(qName) != null) { |
| v.addAll((Vector)symbolTable.getHashMap().get(qName)); |
| } |
| } |
| if(v.size()>0) { |
| collisionCandidates.add(v); |
| } |
| } |
| } |
| Iterator it = collisionCandidates.iterator(); |
| |
| while (it.hasNext()) { |
| Vector v = new Vector( |
| (Vector) it.next()); // New vector we can temporarily add to it |
| |
| // Remove MessageEntries since they are not mapped |
| int index = 0; |
| |
| while (index < v.size()) { |
| if (v.elementAt(index) instanceof MessageEntry) { |
| // Need to resolve a Exception message. |
| MessageEntry msgEntry = (MessageEntry) v.elementAt(index); |
| // AXIS-2900: Only simple type faults generate additional classes; message entries for |
| // complex type faults don't cause any collisions. |
| if (Utils.isFaultComplex(msgEntry) || msgEntry.getDynamicVar(EXCEPTION_CLASS_NAME) == null) { |
| v.removeElementAt(index); |
| } else { |
| index++; |
| } |
| } else { |
| index++; |
| } |
| } |
| |
| if (v.size() > 1) { |
| boolean resolve = true; |
| |
| // Common Special Case: |
| // If a Type and Element have the same QName, and the Element |
| // references the Type, then they are the same class so |
| // don't bother mangling. |
| if (v.size() == 2 && |
| ((v.elementAt(0) instanceof Element && |
| v.elementAt(1) instanceof Type) || |
| (v.elementAt(1) instanceof Element && |
| v.elementAt(0) instanceof Type))) { |
| Element e; |
| Type t; |
| if (v.elementAt(0) instanceof Element) { |
| e = (Element) v.elementAt(0); |
| t = (Type) v.elementAt(1); |
| } else { |
| e = (Element) v.elementAt(1); |
| t = (Type) v.elementAt(0); |
| } |
| |
| BooleanHolder forElement = new BooleanHolder(); |
| QName eType = Utils.getTypeQName(e.getNode(), |
| forElement, false); |
| |
| if ((eType != null) && !forElement.value && eType.equals(t.getQName())) { |
| resolve = false; |
| } |
| } |
| |
| // Other Special Case: |
| // If the names are already different, no mangling is needed. |
| if (resolve) { |
| resolve = false; // Assume false |
| |
| String name = null; |
| |
| for (int i = 0; (i < v.size()) && !resolve; ++i) { |
| SymTabEntry entry = (SymTabEntry) v.elementAt(i); |
| |
| if ((entry instanceof MessageEntry) |
| || (entry instanceof BindingEntry)) { |
| // Need to resolve a exception class name |
| String exceptionClassName = (String) entry.getDynamicVar(EXCEPTION_CLASS_NAME); |
| if (exceptionClassName != null) { |
| if (name == null) { |
| name = exceptionClassName; |
| } else if (name.equals(exceptionClassName)) { |
| resolve = true; |
| } |
| } |
| } else if (name == null) { |
| name = entry.getName(); |
| } else if (name.equals(entry.getName())) { |
| resolve = true; // Need to do resolution |
| } |
| } |
| } |
| |
| // Full Mangle if resolution is necessary. |
| if (resolve) { |
| boolean firstType = true; |
| |
| for (int i = 0; i < v.size(); ++i) { |
| SymTabEntry entry = (SymTabEntry) v.elementAt(i); |
| |
| if (entry instanceof Element) { |
| mangleName(entry, ELEMENT_SUFFIX); |
| |
| // If this global element was defined using |
| // an anonymous type, then need to change the |
| // java name of the anonymous type to match. |
| QName anonQName = |
| new QName(entry.getQName().getNamespaceURI(), |
| SymbolTable.ANON_TOKEN |
| + entry.getQName().getLocalPart()); |
| |
| TypeEntry anonType = |
| symbolTable.getType(anonQName); |
| |
| if (anonType != null) { |
| anonType.setName(entry.getName()); |
| anonTypes.add(anonType); |
| } |
| } else if (entry instanceof TypeEntry) { |
| |
| // Search all other types for java names that match this one. |
| // The sameJavaClass method returns true if the java names are |
| // the same (ignores [] ). |
| if (firstType) { |
| firstType = false; |
| |
| Iterator types = |
| symbolTable.getTypeIndex().values().iterator(); |
| |
| while (types.hasNext()) { |
| TypeEntry type = (TypeEntry) types.next(); |
| |
| if ((type != entry) |
| && (type.getBaseType() == null) |
| && sameJavaClass(entry.getName(), |
| type.getName())) { |
| v.add(type); |
| } |
| } |
| } |
| |
| // If this is an anonymous type, it's name was resolved in |
| // the previous if block. Don't reresolve it. |
| if (!anonTypes.contains(entry)) { |
| // In case that other entry in name collision among |
| // PortTypeEntry, ServiceEntry and BindingEntry |
| |
| boolean needResolve = false; |
| |
| // check collision of TypeEntry with PortTypeEntry, ServiceEtnry and/or BindingEntry |
| for (int j = 0; j < v.size(); j++) { |
| SymTabEntry e = (SymTabEntry) v.elementAt(j); |
| if ((e instanceof PortTypeEntry |
| || e instanceof ServiceEntry |
| || e instanceof BindingEntry)) { |
| needResolve = true; |
| break; |
| } |
| } |
| |
| if (!needResolve) { |
| continue; |
| } |
| |
| // Appended Suffix for avoiding name collisions (JAX-RPC 1.1) |
| boolean isComplexTypeFault = Utils.isFaultComplex(entry); |
| mangleName(entry, isComplexTypeFault ? EXCEPTION_SUFFIX : TYPE_SUFFIX); |
| |
| // should update the class name of ElementEntry which references this type entry |
| Map elementIndex = symbolTable.getElementIndex(); |
| List elements = new ArrayList(elementIndex.values()); |
| for (int j = 0; j < elementIndex.size(); j++) { |
| TypeEntry te = (TypeEntry) elements.get(j); |
| TypeEntry ref = te.getRefType(); |
| if (ref != null && entry.getQName().equals(ref.getQName())) { |
| te.setName(entry.getName()); |
| } |
| } |
| |
| // Need to resolve a complex-type exception message. |
| if (isComplexTypeFault) { |
| // SHOULD update the exception class name of a referencing message entry. |
| List messageEntries = symbolTable.getMessageEntries(); |
| for (int j = 0; j < messageEntries.size(); j++) { |
| MessageEntry messageEntry = (MessageEntry)messageEntries.get(j); |
| if (Utils.isFaultComplex(messageEntry)) { |
| QName exceptionDataType = (QName)messageEntry.getDynamicVar(EXCEPTION_DATA_TYPE); |
| if (((TypeEntry)entry).getQName().equals(exceptionDataType)) { |
| String className = (String)messageEntry.getDynamicVar(EXCEPTION_CLASS_NAME); |
| messageEntry.setDynamicVar(EXCEPTION_CLASS_NAME, className + EXCEPTION_SUFFIX); |
| } |
| } |
| } |
| } |
| } |
| } else if (entry instanceof PortTypeEntry) { |
| mangleName(entry, PORT_TYPE_SUFFIX); // "_Port" --> "_PortType" for JAX-RPC 1.1 |
| } else if (entry instanceof ServiceEntry) { |
| mangleName(entry, SERVICE_SUFFIX); |
| } else if (entry instanceof MessageEntry) { |
| if (!Utils.isFaultComplex(entry)) { |
| String exceptionClassName = (String) entry.getDynamicVar(EXCEPTION_CLASS_NAME); |
| entry.setDynamicVar(EXCEPTION_CLASS_NAME, exceptionClassName + EXCEPTION_SUFFIX); |
| } |
| } |
| // else if (entry instanceof MessageEntry) { |
| // we don't care about messages |
| // } |
| else if (entry instanceof BindingEntry) { |
| BindingEntry bEntry = (BindingEntry) entry; |
| |
| // If there is no literal use, then we never see a |
| // class named directly from the binding name. They |
| // all have suffixes: Stub, Skeleton, Impl. |
| // If there IS literal use, then the SDI will be |
| // named after the binding name, so there is the |
| // possibility of a name clash. |
| if (bEntry.hasLiteral()) { |
| mangleName(entry, BINDING_SUFFIX); |
| } |
| } |
| } |
| } |
| } |
| } |
| } // resolveNameClashes |
| |
| /** |
| * Change the type name of the given symbol table entry into a mangled |
| * form using the given suffix. |
| * |
| * @param entry |
| * @param suffix |
| */ |
| private void mangleName(SymTabEntry entry, String suffix) { |
| String name = entry.getName(); |
| |
| int index = name.indexOf("["); |
| |
| String newName; |
| if (index >= 0) { |
| String pre = name.substring(0, index); |
| String post = name.substring(index); |
| |
| newName = pre + suffix + post; |
| } else { |
| newName = name + suffix; |
| } |
| |
| entry.setName(newName); |
| |
| if (log.isDebugEnabled()) { |
| log.debug("Symbol table of type " + entry.getClass().getName() + " mangled: " + name + " -> " + newName); |
| } |
| } |
| |
| /** |
| * Returns true if same java class, ignore [] |
| * |
| * @param one |
| * @param two |
| * @return |
| */ |
| private boolean sameJavaClass(String one, String two) { |
| |
| int index1 = one.indexOf("["); |
| int index2 = two.indexOf("["); |
| |
| if (index1 > 0) { |
| one = one.substring(0, index1); |
| } |
| |
| if (index2 > 0) { |
| two = two.substring(0, index2); |
| } |
| |
| return one.equals(two); |
| } |
| |
| /** |
| * The --all flag is set on the command line (or generateAll(true) is called |
| * on WSDL2Java). Set all symbols as referenced (except nonSOAP bindings |
| * which we don't know how to deal with). |
| */ |
| protected void setAllReferencesToTrue() { |
| |
| Iterator it = symbolTable.getHashMap().values().iterator(); |
| |
| while (it.hasNext()) { |
| Vector v = (Vector) it.next(); |
| |
| for (int i = 0; i < v.size(); ++i) { |
| SymTabEntry entry = (SymTabEntry) v.elementAt(i); |
| |
| if ((entry instanceof BindingEntry) |
| && ((BindingEntry) entry).getBindingType() |
| != BindingEntry.TYPE_SOAP) { |
| entry.setIsReferenced(false); |
| } else { |
| entry.setIsReferenced(true); |
| } |
| } |
| } |
| } // setAllReferencesToTrue |
| |
| /** |
| * If a binding's type is not TYPE_SOAP, then we don't use that binding |
| * or that binding's portType. |
| * |
| * @param symbolTable |
| */ |
| protected void ignoreNonSOAPBindings(SymbolTable symbolTable) { |
| |
| // Look at all uses of the portTypes. If none of the portType's bindings are of type |
| // TYPE_SOAP, then turn off that portType's isReferenced flag. |
| Vector unusedPortTypes = new Vector(); |
| Vector usedPortTypes = new Vector(); |
| Iterator it = symbolTable.getHashMap().values().iterator(); |
| |
| while (it.hasNext()) { |
| Vector v = (Vector) it.next(); |
| |
| for (int i = 0; i < v.size(); ++i) { |
| SymTabEntry entry = (SymTabEntry) v.elementAt(i); |
| |
| if (entry instanceof BindingEntry) { |
| BindingEntry bEntry = (BindingEntry) entry; |
| Binding binding = bEntry.getBinding(); |
| PortType portType = binding.getPortType(); |
| PortTypeEntry ptEntry = |
| symbolTable.getPortTypeEntry(portType.getQName()); |
| |
| if (bEntry.getBindingType() == BindingEntry.TYPE_SOAP) { |
| |
| // If a binding is of type TYPE_SOAP, then mark its portType used |
| // (ie., add it to the usedPortTypes list. If the portType was |
| // previously marked as unused, unmark it (in other words, remove it |
| // from the unusedPortTypes list). |
| usedPortTypes.add(ptEntry); |
| |
| if (unusedPortTypes.contains(ptEntry)) { |
| unusedPortTypes.remove(ptEntry); |
| } |
| } else { |
| bEntry.setIsReferenced(false); |
| |
| // If a binding is not of type TYPE_SOAP, then mark its portType as |
| // unused ONLY if it hasn't already been marked as used. |
| if (!usedPortTypes.contains(ptEntry)) { |
| unusedPortTypes.add(ptEntry); |
| } |
| } |
| } |
| } |
| } |
| |
| // Go through all the portTypes that are marked as unused and set their isReferenced flags |
| // to false. |
| for (int i = 0; i < unusedPortTypes.size(); ++i) { |
| PortTypeEntry ptEntry = (PortTypeEntry) unusedPortTypes.get(i); |
| |
| ptEntry.setIsReferenced(false); |
| } |
| } // ignoreNonSOAPBindings |
| |
| /** |
| * Method constructSignatures |
| * |
| * @param symbolTable |
| */ |
| protected void constructSignatures(SymbolTable symbolTable) { |
| |
| Iterator it = symbolTable.getHashMap().values().iterator(); |
| |
| while (it.hasNext()) { |
| Vector v = (Vector) it.next(); |
| |
| for (int i = 0; i < v.size(); ++i) { |
| SymTabEntry entry = (SymTabEntry) v.elementAt(i); |
| |
| if (entry instanceof BindingEntry) { |
| BindingEntry bEntry = (BindingEntry) entry; |
| Binding binding = bEntry.getBinding(); |
| PortType portType = binding.getPortType(); |
| Iterator operations = |
| portType.getOperations().iterator(); |
| |
| while (operations.hasNext()) { |
| Operation operation = |
| (Operation) operations.next(); |
| String wsdlOpName = operation.getName(); |
| OperationType type = operation.getStyle(); |
| |
| String javaOpName = getOperationJavaNameHook(bEntry, wsdlOpName); // for derived class |
| if (javaOpName == null) { |
| javaOpName = operation.getName(); |
| } |
| |
| Parameters parameters = |
| bEntry.getParameters(operation); |
| |
| if (OperationType.SOLICIT_RESPONSE.equals(type)) { |
| parameters.signature = |
| " // " |
| + Messages.getMessage("invalidSolResp00", javaOpName); |
| |
| System.err.println( |
| Messages.getMessage("invalidSolResp00", javaOpName)); |
| } else if (OperationType.NOTIFICATION.equals(type)) { |
| parameters.signature = |
| " // " |
| + Messages.getMessage("invalidNotif00", javaOpName); |
| |
| System.err.println( |
| Messages.getMessage("invalidNotif00", javaOpName)); |
| } else { // ONE_WAY or REQUEST_RESPONSE |
| if (parameters != null) { |
| String returnType = getReturnTypeJavaNameHook(bEntry, wsdlOpName); |
| if (returnType != null) { |
| if (parameters.returnParam != null) { // 'void' return type??? |
| parameters.returnParam.getType().setName(returnType); |
| } |
| } |
| for (int j = 0; j < parameters.list.size(); ++j) { |
| Parameter p = (Parameter) parameters.list.get(j); |
| String paramType = getParameterTypeJavaNameHook(bEntry, wsdlOpName, j); |
| if (paramType != null) { |
| p.getType().setName(paramType); |
| } |
| } |
| parameters.signature = |
| constructSignature(parameters, javaOpName); |
| } |
| } |
| } |
| } |
| } |
| } |
| } // constructSignatures |
| |
| protected String getOperationJavaNameHook(BindingEntry bEntry, String wsdlOpName) { |
| return null; |
| } |
| |
| protected String getReturnTypeJavaNameHook(BindingEntry bEntry, String wsdlOpName) { |
| return null; |
| } |
| |
| protected String getParameterTypeJavaNameHook(BindingEntry bEntry, String wsdlOpName, int pos) { |
| return null; |
| } |
| |
| /** |
| * Construct the signature, which is used by both the interface and the stub. |
| * |
| * @param parms |
| * @param opName |
| * @return |
| */ |
| private String constructSignature(Parameters parms, String opName) { |
| |
| String name = JavaUtils.xmlNameToJava(opName); |
| String ret = "void"; |
| |
| if ((parms != null) && (parms.returnParam != null)) { |
| ret = Utils.getParameterTypeName(parms.returnParam); |
| } |
| |
| String signature = " public " + ret + " " + name + "("; |
| boolean needComma = false; |
| |
| for (int i = 0; (parms != null) && (i < parms.list.size()); ++i) { |
| Parameter p = (Parameter) parms.list.get(i); |
| |
| if (needComma) { |
| signature = signature + ", "; |
| } else { |
| needComma = true; |
| } |
| |
| String javifiedName = JavaUtils.xmlNameToJava(p.getName()); |
| |
| if (p.getMode() == Parameter.IN) { |
| signature += Utils.getParameterTypeName(p) + " " + javifiedName; |
| } else { |
| signature += Utils.holder(p, emitter) + " " + javifiedName; |
| } |
| } |
| |
| signature = signature + ") throws java.rmi.RemoteException"; |
| |
| if ((parms != null) && (parms.faults != null)) { |
| |
| // Collect the list of faults into a single string, separated by commas. |
| Iterator i = parms.faults.values().iterator(); |
| |
| while (i.hasNext()) { |
| Fault fault = (Fault) i.next(); |
| String exceptionName = |
| Utils.getFullExceptionName(fault.getMessage(), symbolTable); |
| |
| if (exceptionName != null) { |
| signature = signature + ", " + exceptionName; |
| } |
| } |
| } |
| |
| return signature; |
| } // constructSignature |
| |
| /** |
| * Find all inout/out parameters and add a flag to the Type of that parameter saying a holder |
| * is needed. |
| * |
| * @param symbolTable |
| */ |
| protected void determineIfHoldersNeeded(SymbolTable symbolTable) { |
| |
| Iterator it = symbolTable.getHashMap().values().iterator(); |
| |
| while (it.hasNext()) { |
| Vector v = (Vector) it.next(); |
| |
| for (int i = 0; i < v.size(); ++i) { |
| if (v.get(i) instanceof BindingEntry) { |
| |
| // If entry is a BindingEntry, look at all the Parameters |
| // in its portType |
| BindingEntry bEntry = (BindingEntry) v.get(i); |
| |
| // PortTypeEntry ptEntry = |
| // symbolTable.getPortTypeEntry(bEntry.getBinding().getPortType().getQName()); |
| Iterator operations = |
| bEntry.getParameters().values().iterator(); |
| |
| while (operations.hasNext()) { |
| Parameters parms = (Parameters) operations.next(); |
| |
| for (int j = 0; j < parms.list.size(); ++j) { |
| Parameter p = (Parameter) parms.list.get(j); |
| |
| // If the given parameter is an inout or out parameter, then |
| // set a HOLDER_IS_NEEDED flag using the dynamicVar design. |
| if (p.getMode() != Parameter.IN) { |
| TypeEntry typeEntry = p.getType(); |
| |
| typeEntry.setDynamicVar( |
| JavaTypeWriter.HOLDER_IS_NEEDED, |
| Boolean.TRUE); |
| |
| // If this is a complex then set the HOLDER_IS_NEEDED |
| // for the reftype too. |
| if (!typeEntry.isSimpleType() |
| && (typeEntry.getRefType() != null)) { |
| typeEntry.getRefType().setDynamicVar( |
| JavaTypeWriter.HOLDER_IS_NEEDED, |
| Boolean.TRUE); |
| } |
| |
| // If the type is a DefinedElement, need to |
| // set HOLDER_IS_NEEDED on the anonymous type. |
| QName anonQName = |
| SchemaUtils.getElementAnonQName( |
| p.getType().getNode()); |
| |
| if (anonQName != null) { |
| TypeEntry anonType = |
| symbolTable.getType(anonQName); |
| |
| if (anonType != null) { |
| anonType.setDynamicVar( |
| JavaTypeWriter.HOLDER_IS_NEEDED, |
| Boolean.TRUE); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } // determineIfHoldersNeeded |
| |
| /** |
| * Get TypeMapping to use for translating |
| * QNames to java base types |
| */ |
| BaseTypeMapping btm = null; |
| |
| /** |
| * Method setBaseTypeMapping |
| * |
| * @param btm |
| */ |
| public void setBaseTypeMapping(BaseTypeMapping btm) { |
| this.btm = btm; |
| } |
| |
| /** |
| * Method getBaseTypeMapping |
| * |
| * @return |
| */ |
| public BaseTypeMapping getBaseTypeMapping() { |
| if (btm == null) { |
| btm = new BaseTypeMapping() { |
| |
| public String getBaseName(QName qNameIn) { |
| |
| javax.xml.namespace.QName qName = |
| new javax.xml.namespace.QName(qNameIn.getNamespaceURI(), |
| qNameIn.getLocalPart()); |
| Class cls = |
| emitter.getDefaultTypeMapping().getClassForQName(qName); |
| |
| if (cls == null) { |
| return null; |
| } else { |
| return JavaUtils.getTextClassName(cls.getName()); |
| } |
| } |
| }; |
| } |
| |
| return btm; |
| } |
| |
| /** |
| * Determines whether the QName supplied should be generated by comparing |
| * the namespace for the QName against the included and excluded names. |
| * <ul> |
| * <li>if both the includes and excludes are both empty, |
| * the element is generated</li> |
| * <li>if the namespace is in the includes, |
| * the element is generated</li> |
| * <li>if the namespace is not in the excludes and the includes are empty, |
| * the element will be generated. |
| * <li>if the namespace is only in the excludes, |
| * the element is not generated</li> |
| * <li>if the namespace is not in the includes and the includes are not |
| * empty, the element is not generated</li> |
| * </ul> |
| * @param qName |
| * @return |
| */ |
| protected boolean include(QName qName) { |
| String namespace = |
| (qName != null && qName.getNamespaceURI() != null) |
| ? qName.getNamespaceURI() |
| : ""; |
| |
| boolean doInclude = false; |
| NamespaceSelector selector = new NamespaceSelector(namespace); |
| if (qName == null |
| || emitter == null |
| || emitter.getNamespaceIncludes().contains(selector) |
| || (emitter.getNamespaceIncludes().size() == 0 |
| && !emitter.getNamespaceExcludes().contains(selector))) { |
| doInclude = true; |
| } |
| else { |
| log.info( |
| "excluding code generation for non-included QName:" + qName); |
| |
| } |
| return doInclude; |
| } |
| |
| } // class JavaGeneratorFactory |