tomj 2002/10/03 08:00:55 Modified: java/src/org/apache/axis/i18n Tag: interop4 resource.properties java/src/org/apache/axis/wsdl/toJava Tag: interop4 JavaTestCaseWriter.java JavaStubWriter.java JavaFaultWriter.java JavaDefinitionWriter.java Log: Add more changes for the correct processing of fault data. Some error checking and defensive coding changes. Get a (more) correct namespace in the writeDetails() emitted function. We have a problem in that the namespace of a fault can change per operation depending on the WSDL, and the function we emit to write the details element needs to know that namespace. Probably need to get the OperationDesc from the Serailization/Message context and have deploy writer put the fault info in to the WSDD. Still don't emit writeDetails() element for complex type faults, but simple types are working. Revision Changes Path No revision No revision 1.9.2.1 +2 -0 xml-axis/java/src/org/apache/axis/i18n/resource.properties Index: resource.properties =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/i18n/resource.properties,v retrieving revision 1.9 retrieving revision 1.9.2.1 diff -u -r1.9 -r1.9.2.1 --- resource.properties 26 Sep 2002 20:32:55 -0000 1.9 +++ resource.properties 3 Oct 2002 15:00:54 -0000 1.9.2.1 @@ -1031,3 +1031,5 @@ unmatchedOp=Binding operation has no corresponding portType operation: name = {0}, input name = {1}, output name = {2} noOperationForQName=Couldn't find an appropriate operation for XML QName {0} noParmDesc=operation description is missing parameter description! + +noBindingFault=ERROR: Unable to find fault "{0}" in operation "{1}", in binding {2}. \ No newline at end of file No revision No revision 1.44.2.2 +20 -7 xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaTestCaseWriter.java Index: JavaTestCaseWriter.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/toJava/JavaTestCaseWriter.java,v retrieving revision 1.44.2.1 retrieving revision 1.44.2.2 diff -u -r1.44.2.1 -r1.44.2.2 --- JavaTestCaseWriter.java 1 Oct 2002 20:38:51 -0000 1.44.2.1 +++ JavaTestCaseWriter.java 3 Oct 2002 15:00:55 -0000 1.44.2.2 @@ -180,15 +180,23 @@ String javaOpName = Utils.xmlNameToJavaClass(op.getName()); String testMethodName = "test" + counter++ + portName + javaOpName; - pw.println(" public void " + testMethodName + "() {"); + pw.println(" public void " + testMethodName + "() throws Exception {"); String bindingType = (String) bEntry.getDynamicVar(JavaBindingWriter.INTERFACE_NAME); writeBindingAssignment(pw, bindingType, portName); - pw.println(" try {"); + + pw.println(" // Test operation"); + String indent = ""; + Map faultMap = op.getFaults(); + if (faultMap != null && faultMap.size() > 0) { + // we are going to catch fault Exceptions + pw.println(" try {"); + indent = " "; + } if (params.returnParam != null) { TypeEntry returnType = params.returnParam.getType(); - pw.print(" "); + pw.print(" " + indent); pw.print(Utils.getParameterTypeName(params.returnParam)); pw.print(" value = "); @@ -204,7 +212,7 @@ } } - pw.print(" "); + pw.print (" " + indent); if (params.returnParam != null) { pw.print("value = "); @@ -246,9 +254,9 @@ pw.println(");"); - pw.println(" }"); - - Map faultMap = op.getFaults(); + if (faultMap != null && faultMap.size() > 0) { + pw.println(" }"); + } if (faultMap != null) { Iterator i = faultMap.values().iterator(); @@ -265,6 +273,10 @@ pw.println(" }"); } } + + pw.println(" " + indent + "// TBD - validate results"); + + /* pw.println(" catch (java.rmi.RemoteException re) {"); pw.print(" "); pw.println("throw new junit.framework.AssertionFailedError(\"Remote Exception caught: \" + re);"); @@ -274,6 +286,7 @@ pw.println(" // Unsigned constructors can throw - ignore"); pw.println(" }"); } + */ pw.println(" }"); pw.println(); } 1.98.2.3 +13 -2 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.2 retrieving revision 1.98.2.3 diff -u -r1.98.2.2 -r1.98.2.3 --- JavaStubWriter.java 2 Oct 2002 15:14:56 -0000 1.98.2.2 +++ JavaStubWriter.java 3 Oct 2002 15:00:55 -0000 1.98.2.3 @@ -401,9 +401,9 @@ } // partTypes /** - * This function returns the faults in an operation + * This function writes the regsiterFaultInfo API calls */ - private void writeFaultInfo(PrintWriter pw, PortType portType) { + 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 @@ -422,11 +422,22 @@ // 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();) { 1.14.2.2 +40 -13 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.1 retrieving revision 1.14.2.2 diff -u -r1.14.2.1 -r1.14.2.2 --- JavaFaultWriter.java 1 Oct 2002 20:38:51 -0000 1.14.2.1 +++ JavaFaultWriter.java 3 Oct 2002 15:00:55 -0000 1.14.2.2 @@ -58,28 +58,42 @@ import java.io.PrintWriter; import java.util.Vector; +import java.util.HashMap; +import java.util.List; +import java.util.Iterator; +import java.util.Collection; import javax.wsdl.Fault; +import javax.wsdl.BindingFault; +import javax.wsdl.PortType; +import javax.wsdl.extensions.soap.SOAPFault; import javax.xml.namespace.QName; import org.apache.axis.wsdl.symbolTable.Parameter; import org.apache.axis.wsdl.symbolTable.SymbolTable; /** -* This is Wsdl2java's Fault Writer. It writes the <faultName>.java file. -* NOTE: this must be rewritten. It doesn't follow JAX-RPC. -*/ + * This is Wsdl2java's Fault Writer. It writes the <faultName>.java file. + * + * NOTE: This only writes simple type faults, the JavaTypeWriter emits + * faults that are complex types. + */ public class JavaFaultWriter extends JavaClassWriter { private Fault fault; private SymbolTable symbolTable; + private BindingFault bindingFault; /** * Constructor. */ - protected JavaFaultWriter(Emitter emitter, QName qname, Fault fault, SymbolTable symbolTable) { + protected JavaFaultWriter(Emitter emitter, + SymbolTable symbolTable, + Fault fault, + BindingFault bindingFault) { super(emitter, Utils.getFullExceptionName(fault, symbolTable), "fault"); this.fault = fault; this.symbolTable = symbolTable; + this.bindingFault = bindingFault; } // ctor /** @@ -138,14 +152,27 @@ } pw.println(" }"); } - - // Hack alert! - // We need a QName for the exception part that we are going to - // serialize, but <part name=""> isn't NOT a QName - go figure - // So we will use the namespace of the Message, and the name of the part - // NOTE: we do the same thing when creating the fault map in JavaStubWriter - String namespace = fault.getMessage().getQName().getNamespaceURI(); - + + // 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). + + // We do the same thing in JavaStubWriter.java + String namespace = ""; + 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; + namespace = sf.getNamespaceURI(); + } + } + } // method that serializes exception data (writeDetail) pw.println(); pw.println(" /**"); @@ -158,8 +185,8 @@ QName qname = new QName(namespace, 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(" }"); } + pw.println(" }"); } // writeFileBody } // class JavaFaultWriter 1.10.4.2 +59 -23 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.1 retrieving revision 1.10.4.2 diff -u -r1.10.4.1 -r1.10.4.2 --- JavaDefinitionWriter.java 1 Oct 2002 20:38:51 -0000 1.10.4.1 +++ JavaDefinitionWriter.java 3 Oct 2002 15:00:55 -0000 1.10.4.2 @@ -68,6 +68,9 @@ import javax.wsdl.Import; import javax.wsdl.Operation; import javax.wsdl.PortType; +import javax.wsdl.BindingFault; +import javax.wsdl.Binding; +import javax.wsdl.BindingOperation; import javax.xml.namespace.QName; import org.apache.axis.wsdl.gen.Generator; @@ -75,17 +78,14 @@ import org.apache.axis.wsdl.symbolTable.SymbolTable; import org.apache.axis.wsdl.symbolTable.MessageEntry; import org.apache.axis.utils.Messages; +import org.apache.axis.Message; /** * This is Wsdl2java's Definition Writer. * It currently writes the following files: - * deploy.xml, undeploy.xml and Faults as needed. + * Faults as needed. */ public class JavaDefinitionWriter implements Generator { -/* - protected Writer deployWriter = null; - protected Writer undeployWriter = null; -*/ protected Emitter emitter; protected Definition definition; protected SymbolTable symbolTable; @@ -95,10 +95,6 @@ */ public JavaDefinitionWriter(Emitter emitter, Definition definition, SymbolTable symbolTable) { -/* - deployWriter = new JavaDeployWriter(emitter, definition, symbolTable); - undeployWriter = new JavaUndeployWriter(emitter, definition, symbolTable); -*/ this.emitter = emitter; this.definition = definition; this.symbolTable = symbolTable; @@ -108,18 +104,12 @@ * Write other items from the definition as needed. */ public void generate() throws IOException { -/* - if (emitter.generateServerSide()) { - deployWriter.write(); - undeployWriter.write(); - } -*/ writeFaults(); } // generate /** - * Write all the faults. - * + * Write all the simple type faults. + * The complexType Faults are automatically handled by JavaTypeWriter. * The fault name is derived from the fault message name per JAX-RPC */ private void writeFaults() throws IOException { @@ -130,7 +120,8 @@ Iterator fi = faults.entrySet().iterator(); while (fi.hasNext()) { Map.Entry entry = (Map.Entry) fi.next(); - Fault fault = (Fault) entry.getKey(); + FaultInfo faultInfo = (FaultInfo) entry.getValue(); + Fault fault = faultInfo.fault; // Generate the 'Simple' Faults. // The complexType Faults are automatically handled @@ -148,10 +139,14 @@ } } if (emitSimpleFault) { - QName faultQName = (QName) entry.getValue(); try { - new JavaFaultWriter(emitter, faultQName, fault, - symbolTable).generate(); + JavaFaultWriter writer = + new JavaFaultWriter(emitter, + symbolTable, + faultInfo.fault, + faultInfo.bindingFault); + // Go write the file + writer.generate(); } catch (DuplicateFileException dfe) { System.err.println( Messages.getMessage("fileExistError00", dfe.getFileName())); @@ -161,6 +156,13 @@ } // writeFaults /** + * Holder structure for fault information + */ + public class FaultInfo { + public Fault fault; + public BindingFault bindingFault; + } + /** * Collect all of the faults used in this definition. */ private HashSet importedFiles = new HashSet(); @@ -203,12 +205,46 @@ // prevent duplicates if (! faultList.contains(name) ) { faultList.add(name); - faults.put(f, f.getMessage().getQName()); + 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 + 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 } // collectFaults - + } // class JavaDefinitionWriter