tomj 2002/10/04 16:36:02 Modified: java/src/org/apache/axis/wsdl/toJava Tag: interop4 Utils.java JavaStubWriter.java JavaFaultWriter.java JavaDeployWriter.java JavaDefinitionWriter.java JavaBeanFaultWriter.java Log: Work in progress for Faults - DOESN'T WORK YET. Now are collecting fault information in the SymbolTable, then using it in the writers. Glen and I are still working on it, checking in so we can work on it at home. Revision Changes Path No revision No revision 1.58.4.2 +34 -0 xml-axis/java/src/org/apache/axis/wsdl/toJava/Utils.java Index: Utils.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/Utils.java,v retrieving revision 1.58.4.1 retrieving revision 1.58.4.2 diff -u -r1.58.4.1 -r1.58.4.2 --- Utils.java 1 Oct 2002 20:38:51 -0000 1.58.4.1 +++ Utils.java 4 Oct 2002 23:36:02 -0000 1.58.4.2 @@ -57,6 +57,7 @@ import org.apache.axis.Constants; import org.apache.axis.utils.JavaUtils; +import org.apache.axis.utils.Messages; import org.apache.axis.wsdl.symbolTable.BindingEntry; import org.apache.axis.wsdl.symbolTable.CollectionTE; @@ -78,8 +79,10 @@ import javax.wsdl.Message; import javax.wsdl.Operation; import javax.wsdl.Part; +import javax.wsdl.BindingFault; import javax.wsdl.extensions.ExtensibilityElement; import javax.wsdl.extensions.soap.SOAPBody; +import javax.wsdl.extensions.soap.SOAPFault; import javax.xml.namespace.QName; import javax.xml.rpc.holders.BooleanHolder; @@ -269,6 +272,37 @@ } } // isFaultComplex + /** + * Return the QName of a fault + * + * Can return null if no parts in fault + */ + public static QName getFaultQName(Fault fault, SOAPFault soapFault) { + // get the name of the part - there can be only one! + Message message = fault.getMessage(); + Map parts = message.getParts(); + // If no parts, skip it + if (parts.size() == 0) { + return null; + } + + // We have 2 cases + // - part is an element, use element name and namespace + // - part is a type, use part name and binding namespace + Part part = (Part) parts.values().iterator().next(); + + // Someone should have already made sure that + // if use=literal, no use of namespace on the soap:fault + // if use=encoded, no use of element on the part + if (part.getTypeName() != null) { + String namespace = soapFault.getNamespaceURI(); + // Now make a QName + return new QName(namespace, part.getName()); + } else { + // Use the element's QName for the fault + return part.getElementName(); + } + } /** * If the specified node represents a supported JAX-RPC enumeration, * a Vector is returned which contains the base type and the enumeration values. 1.98.2.4 +37 -71 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaStubWriter.java Index: JavaStubWriter.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaStubWriter.java,v retrieving revision 1.98.2.3 retrieving revision 1.98.2.4 diff -u -r1.98.2.3 -r1.98.2.4 --- JavaStubWriter.java 3 Oct 2002 15:00:55 -0000 1.98.2.3 +++ JavaStubWriter.java 4 Oct 2002 23:36:02 -0000 1.98.2.4 @@ -83,6 +83,7 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import java.util.ArrayList; /** * This is Wsdl2java's stub writer. It writes the <BindingName>Stub.java @@ -196,9 +197,6 @@ typeMappingCount++; } - // Register fault/exception information - writeFaultInfo(pw, portType); - pw.println(" }"); pw.println(); pw.println(" private org.apache.axis.client.Call createCall() throws java.rmi.RemoteException {"); @@ -403,76 +401,40 @@ /** * This function writes the regsiterFaultInfo API calls */ - private void writeFaultInfo(PrintWriter pw, PortType portType) throws IOException { - // Where we remember which QName we have already written out - Vector emitted = new Vector(); - // Get all the faults from all the operations - List operations = portType.getOperations(); - for (int i = 0; i < operations.size(); ++i) { - Operation operation = (Operation) operations.get(i); - Map faults = operation.getFaults(); - BindingOperation bindOp = - binding.getBindingOperation(operation.getName(), null, null); + private void writeFaultInfo(PrintWriter pw, BindingOperation bindOp) throws IOException { + Map faultMap = bEntry.getFaults(); + // Get the list of faults for this operation + ArrayList faults = (ArrayList) faultMap.get(bindOp); + + // check for no faults + if (faults == null) { + return; + } + // For each fault, register its information + for (Iterator faultIt = faults.iterator(); faultIt.hasNext();) { + JavaDefinitionWriter.FaultInfo info = (JavaDefinitionWriter.FaultInfo) faultIt.next(); - if (faults != null) { - Iterator it = faults.values().iterator(); - while (it.hasNext()) { - Fault fault = (Fault) it.next(); - - // get the name of the part - there can be only one! - Message message = fault.getMessage(); - Map parts = message.getParts(); - // If no parts, skip it - if (parts.size() == 0) { - continue; - } - String partName = (String) parts.keySet().iterator().next(); - - // Use the namespace in the binding for this fault - // NOTE: we do the same thing when writing the fault in JavaFaultWriter - BindingFault bindFault = bindOp.getBindingFault(fault.getName()); - if (bindFault == null) { - throw new IOException( - Messages.getMessage("noBindingFault", - new String[] {fault.getName(), - bindOp.getName(), - binding.getQName().toString()})); - } - List extList = bindFault.getExtensibilityElements(); - String namespace = ""; - for (Iterator iterator = extList.iterator(); iterator.hasNext();) { - Object o = (Object) iterator.next(); - if (o instanceof SOAPFault) { - SOAPFault sf = (SOAPFault) o; - namespace = sf.getNamespaceURI(); - } - } - - // Now make a QName - QName qname = new QName(namespace, partName); - - if (emitted.contains(qname)) { - continue; - } - - // Remember that we have already registered this name - emitted.add(qname); - - // Get the Exception class name - String className = Utils.getFullExceptionName(fault, symbolTable); - - // Get the xmlType of the exception data - QName xmlType = Utils.getFaultDataType(fault, symbolTable); - - // output the registration API call - pw.print(" ((org.apache.axis.client.Service)service).registerFaultInfo("); - pw.print( Utils.getNewQName(qname) + ", "); - pw.print( className + ".class, "); - pw.print( Utils.getNewQName(xmlType) + ", "); - pw.print( Utils.isFaultComplex(fault, symbolTable)); - pw.println(");"); - } + Fault fault = info.fault; + QName qname = Utils.getFaultQName(fault, info.soapFault); + + // if no parts in fault, skip it! + if (qname == null) { + continue; } + + // Get the Exception class name + String className = Utils.getFullExceptionName(fault, symbolTable); + + // Get the xmlType of the exception data + QName xmlType = Utils.getFaultDataType(fault, symbolTable); + + // output the registration API call + pw.print(" _call.addFault("); + pw.print( Utils.getNewQName(qname) + ", "); + pw.print( className + ".class, "); + pw.print( Utils.getNewQName(xmlType) + ", "); + pw.print( Utils.isFaultComplex(fault, symbolTable)); + pw.println(");"); } } @@ -640,6 +602,10 @@ else { pw.println(" _call.setReturnType(org.apache.axis.encoding.XMLType.AXIS_VOID);"); } + + // Register fault/exception information for this operation + writeFaultInfo(pw, operation); + // SoapAction if (soapAction != null) { 1.14.2.4 +9 -20 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaFaultWriter.java Index: JavaFaultWriter.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaFaultWriter.java,v retrieving revision 1.14.2.3 retrieving revision 1.14.2.4 diff -u -r1.14.2.3 -r1.14.2.4 --- JavaFaultWriter.java 3 Oct 2002 17:56:35 -0000 1.14.2.3 +++ JavaFaultWriter.java 4 Oct 2002 23:36:02 -0000 1.14.2.4 @@ -81,7 +81,7 @@ public class JavaFaultWriter extends JavaClassWriter { private Fault fault; private SymbolTable symbolTable; - private BindingFault bindingFault; + private SOAPFault soapFault; /** * Constructor. @@ -89,11 +89,11 @@ protected JavaFaultWriter(Emitter emitter, SymbolTable symbolTable, Fault fault, - BindingFault bindingFault) { + SOAPFault soapFault) { super(emitter, Utils.getFullExceptionName(fault, symbolTable), "fault"); this.fault = fault; this.symbolTable = symbolTable; - this.bindingFault = bindingFault; + this.soapFault = soapFault; } // ctor /** @@ -109,23 +109,14 @@ protected void writeFileBody(PrintWriter pw) throws IOException { Vector params = new Vector(); - String faultNamespace = ""; boolean literal = false; - // Have to get namespace and use information (literal/encoded) - // for fault from Binding. - if (bindingFault != null) { - List extList = bindingFault.getExtensibilityElements(); - for (Iterator iterator = extList.iterator(); iterator.hasNext();) { - Object o = (Object) iterator.next(); - if (o instanceof SOAPFault) { - SOAPFault sf = (SOAPFault) o; - faultNamespace = sf.getNamespaceURI(); - if ("literal".equalsIgnoreCase(sf.getUse())) { - literal = true; - } - } + // Have to get use information (literal/encoded) for fault from Binding. + if (soapFault != null) { + if ("literal".equalsIgnoreCase(soapFault.getUse())) { + literal = true; } } + symbolTable.getParametersFromParts(params, fault.getMessage().getOrderedParts(null), literal, @@ -182,12 +173,10 @@ pw.println(" /**"); pw.println(" * Writes the exception data to the faultDetails"); pw.println(" */"); - pw.println(" public void writeDetails(org.apache.axis.encoding.SerializationContext context) throws java.io.IOException {"); + pw.println(" public void writeDetails(javax.xml.namespace.QName qname, org.apache.axis.encoding.SerializationContext context) throws java.io.IOException {"); for (int i = 0; i < params.size(); i++) { Parameter param = (Parameter)params.get(i); String variable = param.getName(); - QName qname = new QName(faultNamespace, param.getQName().getLocalPart()); - pw.println(" javax.xml.namespace.QName qname = " + Utils.getNewQName(qname) + ";"); pw.println(" context.serialize(qname, null, " + Utils.wrapPrimitiveType(param.getType(), variable) + ");"); } pw.println(" }"); 1.65.2.2 +40 -12 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaDeployWriter.java Index: JavaDeployWriter.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaDeployWriter.java,v retrieving revision 1.65.2.1 retrieving revision 1.65.2.2 diff -u -r1.65.2.1 -r1.65.2.2 --- JavaDeployWriter.java 4 Oct 2002 13:06:07 -0000 1.65.2.1 +++ JavaDeployWriter.java 4 Oct 2002 23:36:02 -0000 1.65.2.2 @@ -60,6 +60,7 @@ import java.util.Iterator; import java.util.Map; import java.util.Vector; +import java.util.ArrayList; import javax.wsdl.Binding; import javax.wsdl.BindingOperation; @@ -177,7 +178,7 @@ if (bEntry.getBindingType() != BindingEntry.TYPE_SOAP) { continue; } - writeDeployPort(pw, myPort, myService); + writeDeployPort(pw, myPort, myService, bEntry); } } } //writeDeployServices @@ -185,8 +186,10 @@ /** * Write out bean mappings for each type */ - protected void writeDeployTypes(PrintWriter pw, Binding binding, - boolean hasLiteral, boolean hasMIME) throws IOException { + protected void writeDeployTypes(PrintWriter pw, + Binding binding, + boolean hasLiteral, + boolean hasMIME) throws IOException { Vector types = symbolTable.getTypes(); pw.println(); @@ -275,9 +278,10 @@ /** * Write out deployment and undeployment instructions for given WSDL port */ - protected void writeDeployPort(PrintWriter pw, Port port, Service service) throws IOException { - Binding binding = port.getBinding(); - BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName()); + protected void writeDeployPort(PrintWriter pw, + Port port, + Service service, + BindingEntry bEntry) throws IOException { String serviceName = port.getName(); boolean hasLiteral = bEntry.hasLiteral(); @@ -310,8 +314,8 @@ pw.println(" <parameter name=\"sendMultiRefs\" value=\"false\"/>"); } - writeDeployBinding(pw, binding); - writeDeployTypes(pw, binding, hasLiteral, hasMIME); + writeDeployBinding(pw, bEntry); + writeDeployTypes(pw, bEntry.getBinding(), hasLiteral, hasMIME); pw.println(" </service>"); } //writeDeployPort @@ -319,8 +323,9 @@ /** * Write out deployment instructions for given WSDL binding */ - protected void writeDeployBinding(PrintWriter pw, Binding binding) throws IOException { - BindingEntry bEntry = symbolTable.getBindingEntry(binding.getQName()); + protected void writeDeployBinding(PrintWriter pw, + BindingEntry bEntry) throws IOException { + Binding binding = bEntry.getBinding(); String className = bEntry.getName(); if (emitter.isSkeletonWanted()) className += "Skeleton"; @@ -369,10 +374,16 @@ returnType = Utils.getXSIType(params.returnParam); } + // Get the operations faults + Map faultMap = bEntry.getFaults(); + ArrayList faults = null; + if (faultMap != null) { + faults = (ArrayList) faultMap.get(bindingOper); + } // Write the operation metadata writeOperation(pw, javaOperName, elementQName, returnQName, returnType, - params, binding.getQName()); + params, binding.getQName(), faults); } } } @@ -399,7 +410,8 @@ QName returnQName, QName returnType, Parameters params, - QName bindingQName) { + QName bindingQName, + ArrayList faults) { pw.print(" <operation name=\"" + javaOperName + "\""); if (elementQName != null) { pw.print(" qname=\"" + @@ -443,6 +455,22 @@ pw.print(" mode=\"" + getModeString(param.getMode()) + "\""); } pw.println("/>"); + } + if (faults != null) { + for (Iterator iterator = faults.iterator(); iterator.hasNext();) { + JavaDefinitionWriter.FaultInfo faultInfo = + (JavaDefinitionWriter.FaultInfo) iterator.next(); + QName faultQName = Utils.getFaultQName(faultInfo.fault, + faultInfo.soapFault); + if (faultQName != null) { + String className = Utils.getFullExceptionName(faultInfo.fault, symbolTable); + pw.print(" <fault"); + pw.print(" qname=\"" + + Utils.genQNameAttributeString(faultQName, "fns") + "\""); + pw.print(" class=\"" + className+ "\""); + pw.println("/>"); + } + } } pw.println(" </operation>"); 1.10.4.4 +40 -69 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaDefinitionWriter.java Index: JavaDefinitionWriter.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaDefinitionWriter.java,v retrieving revision 1.10.4.3 retrieving revision 1.10.4.4 diff -u -r1.10.4.3 -r1.10.4.4 --- JavaDefinitionWriter.java 4 Oct 2002 13:06:07 -0000 1.10.4.3 +++ JavaDefinitionWriter.java 4 Oct 2002 23:36:02 -0000 1.10.4.4 @@ -62,6 +62,7 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import java.util.ArrayList; import javax.wsdl.Definition; import javax.wsdl.Fault; @@ -71,11 +72,13 @@ import javax.wsdl.BindingFault; import javax.wsdl.Binding; import javax.wsdl.BindingOperation; +import javax.wsdl.extensions.soap.SOAPFault; import org.apache.axis.wsdl.gen.Generator; import org.apache.axis.wsdl.symbolTable.SymbolTable; import org.apache.axis.wsdl.symbolTable.MessageEntry; +import org.apache.axis.wsdl.symbolTable.BindingEntry; import org.apache.axis.utils.Messages; /** @@ -111,15 +114,22 @@ * The fault name is derived from the fault message name per JAX-RPC */ private void writeFaults() throws IOException { - HashMap faults = new HashMap(); + ArrayList faults = new ArrayList(); collectFaults(definition, faults); + + // Fault classes we're actually writing (for dup checking) + HashSet generatedFaults = new HashSet(); // iterate over fault list, emitting code. - Iterator fi = faults.entrySet().iterator(); + Iterator fi = faults.iterator(); while (fi.hasNext()) { - Map.Entry entry = (Map.Entry) fi.next(); - FaultInfo faultInfo = (FaultInfo) entry.getValue(); + FaultInfo faultInfo = (FaultInfo) fi.next(); Fault fault = faultInfo.fault; + String name = Utils.getFullExceptionName(fault, symbolTable); + if (generatedFaults.contains(name)) { + continue; + } + generatedFaults.add(name); // Generate the 'Simple' Faults. // The complexType Faults are automatically handled @@ -129,8 +139,7 @@ boolean emitSimpleFault = true; if (me != null) { Boolean complexTypeFault = (Boolean) - me.getDynamicVar( - JavaGeneratorFactory.COMPLEX_TYPE_FAULT); + me.getDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT); if (complexTypeFault != null && complexTypeFault.booleanValue()) { emitSimpleFault = false; @@ -142,7 +151,7 @@ new JavaFaultWriter(emitter, symbolTable, faultInfo.fault, - faultInfo.bindingFault); + faultInfo.soapFault); // Go write the file writer.generate(); } catch (DuplicateFileException dfe) { @@ -156,16 +165,21 @@ /** * Holder structure for fault information */ - public class FaultInfo { + public static class FaultInfo { + public FaultInfo(Fault fault, SOAPFault soapFault) { + this.fault = fault; + this.soapFault = soapFault; + } + public Fault fault; - public BindingFault bindingFault; + public SOAPFault soapFault; } + /** * Collect all of the faults used in this definition. */ private HashSet importedFiles = new HashSet(); - private void collectFaults(Definition def, Map faults) throws IOException { - Vector faultList = new Vector(); + private void collectFaults(Definition def, ArrayList faults) throws IOException { Map imports = def.getImports(); Object[] importValues = imports.values().toArray(); for (int i = 0; i < importValues.length; ++i) { @@ -181,68 +195,25 @@ } } } - Map portTypes = def.getPortTypes(); - Iterator pti = portTypes.values().iterator(); - // collect referenced faults in a list - while (pti.hasNext()) { - PortType portType = (PortType) pti.next(); - - // Don't emit faults that are not referenced. - if (symbolTable.getPortTypeEntry(portType.getQName()). - isReferenced()) { - List operations = portType.getOperations(); - for (int i = 0; i < operations.size(); ++i) { - Operation operation = (Operation) operations.get(i); - Map opFaults = operation.getFaults(); - Iterator fi = opFaults.values().iterator(); - while (fi.hasNext()) { - Fault f = (Fault) fi.next(); - String name = Utils.getFullExceptionName( - f, - symbolTable); - // prevent duplicates - if (! faultList.contains(name) ) { - faultList.add(name); - FaultInfo faultInfo = new FaultInfo(); - faultInfo.fault = f; - faults.put(f.getName(), faultInfo); - } - } - } - } - } - - // We now have a map of FullExceptionName -> FaultInfo - // Now we traverse the bindings to fill in more info + + // Traverse the bindings to find faults Map bindings = def.getBindings(); Iterator bindi = bindings.values().iterator(); while (bindi.hasNext()) { Binding binding = (Binding) bindi.next(); - - if (symbolTable.getBindingEntry(binding.getQName()).isReferenced()) { - List operations = binding.getBindingOperations(); - for (int i = 0; i < operations.size(); ++i) { - BindingOperation operation = (BindingOperation) operations.get(i); - Map bindFaults = operation.getBindingFaults(); - Iterator fi = bindFaults.values().iterator(); - while (fi.hasNext()) { - BindingFault bFault = (BindingFault) fi.next(); - FaultInfo faultInfo = (FaultInfo) faults.get(bFault.getName()); - if (faultInfo == null) { - // This should NOT happen! - throw new IOException( - Messages.getMessage("noBindingFault", - new String[] {bFault.getName(), - operation.getName(), - binding.getQName().toString()})); - } - faultInfo.bindingFault = bFault; - // put the updated entry back in the map - faults.put(bFault.getName(), faultInfo); - } // while - } // for - } // if binding referenced - } // iterate bindings + BindingEntry entry = symbolTable.getBindingEntry(binding.getQName()); + if (entry.isReferenced()) { + // use the map of bindingOperation -> fault info + // created in SymbolTable + Map faultMap = entry.getFaults(); + Iterator it = faultMap.values().iterator(); + while (it.hasNext()) { + ArrayList list = (ArrayList) it.next(); + // Accumulate total list of faults + faults.addAll(list); + } + } + } } // collectFaults } // class JavaDefinitionWriter 1.2.4.1 +32 -0 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaBeanFaultWriter.java Index: JavaBeanFaultWriter.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaBeanFaultWriter.java,v retrieving revision 1.2 retrieving revision 1.2.4.1 diff -u -r1.2 -r1.2.4.1 --- JavaBeanFaultWriter.java 8 Aug 2002 15:17:11 -0000 1.2 +++ JavaBeanFaultWriter.java 4 Oct 2002 23:36:02 -0000 1.2.4.1 @@ -55,8 +55,13 @@ package org.apache.axis.wsdl.toJava; import java.util.Vector; +import java.io.PrintWriter; +import java.io.IOException; import org.apache.axis.wsdl.symbolTable.TypeEntry; +import org.apache.axis.wsdl.symbolTable.Parameter; + +import javax.xml.namespace.QName; /** * This is Wsdl2java's Complex Faylt Writer. @@ -111,4 +116,31 @@ return extendsText; } + /** + * Write the Exception serialization code + * + * NOTE: This function is written in JavaFaultWriter.java also. + */ + protected void writeFileFooter(PrintWriter pw) throws IOException { + // PROBLEM: we need to have the Exception class serialize itself + // with the correct namespace, which can change depending on which + // operation the exception is thrown from. This event seems unlikely + // so for the time being we will use the namespace from the first + // binding operation we find, which is passed in as construction time + // Note that bindingFault can be null if this fault is never referenced + // in a binding (WSDL2Java --all switch). + + // method that serializes this exception (writeDetail) + pw.println(); + pw.println(" /**"); + pw.println(" * Writes the exception data to the faultDetails"); + pw.println(" */"); + pw.println(" public void writeDetails(javax.xml.namespace.QName qname, org.apache.axis.encoding.SerializationContext context) throws java.io.IOException {"); +/* pw.println(" javax.xml.namespace.QName qname = new QName();"); + pw.println(" context.serialize(qname, null, this);"); +*/ + pw.println(" }"); + + super.writeFileFooter(pw); + } // writeFileFooter } // class JavaBeanFaultWriter