Dang! Sorry, folks. Looks like I don't know what I'm doing. I was trying to commit some header work into a branch, not the head. I COULD leave this stuff here in the head, it's only new symbol table stuff and until something uses the new symbol table info, our functionality won't change. But if folks want me to rip it out, I'll understand. The rest of the header stuff I DO want to put into a branch, and I won't commit it until I figure out what I'm doing wrong. Russell Butek [EMAIL PROTECTED] [EMAIL PROTECTED] on 10/02/2002 01:21:30 PM Please respond to [EMAIL PROTECTED] To: [EMAIL PROTECTED] cc: Subject: cvs commit: xml-axis/java/src/org/apache/axis/wsdl/symbolTable BindingEntry.java Parameter.java SymbolTable.java butek 2002/10/02 11:21:30 Modified: java/src/org/apache/axis/wsdl/symbolTable BindingEntry.java Parameter.java SymbolTable.java Log: First cut at explicit header support. This just adds support to the symbol table. Revision Changes Path 1.4 +182 -4 xml-axis/java/src/org/apache/axis/wsdl/symbolTable/BindingEntry.java Index: BindingEntry.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/symbolTable/BindingEntry.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- BindingEntry.java 2 Aug 2002 12:55:33 -0000 1.3 +++ BindingEntry.java 2 Oct 2002 18:21:29 -0000 1.4 @@ -89,9 +89,13 @@ private HashMap parameters = new HashMap(); // This is a map of a map. It's a map keyed on operation name whose values - // are maps keyed on parameter name. + // are maps keyed on parameter name. The ultimate values are simple Strings. private Map mimeTypes; - + + // This is a map of a map. It's a map keyed on operation name whose values + // are maps keyed on parameter name. The ultimate values are simple + // Booleans. + private Map headerParameters; /** * Construct a BindingEntry from a WSDL4J Binding object and the additional binding info: @@ -99,19 +103,59 @@ * contain the input/output/fault body type information. */ public BindingEntry(Binding binding, int bindingType, int bindingStyle, - boolean hasLiteral, HashMap attributes, Map mimeTypes) { + boolean hasLiteral, HashMap attributes, Map mimeTypes, + Map headerParameters) { super(binding.getQName()); this.binding = binding; this.bindingType = bindingType; this.bindingStyle = bindingStyle; this.hasLiteral = hasLiteral; - this.attributes = attributes; + if (attributes == null) { + this.attributes = new HashMap(); + } + else { + this.attributes = attributes; + } if (mimeTypes == null) { this.mimeTypes = new HashMap(); } else { this.mimeTypes = mimeTypes; } + if (headerParameters == null) { + this.headerParameters = new HashMap(); + } + else { + this.headerParameters = headerParameters; + } + } // ctor + + /** + * This is a minimal constructor. Everything will be set up with + * defaults. If the defaults aren't desired, then the appropriate + * setter method should be called. The defaults are: + * bindingType = TYPE_UNKNOWN + * bindingStyle = STYLE_DOCUMENT + * hasLiteral = false + * operation inputBodyTypes = USE_ENCODED + * operation outputBodyTypes = USE_ENCODED + * operation faultBodyTypes = USE_ENCODED + * mimeTypes = null + +The caller of this constructor should + * also call the various setter methods to fully fill out this object: + * setBindingType, setBindingStyle, setHasLiteral, setAttribute, + * setMIMEType. + */ + public BindingEntry(Binding binding) { + super(binding.getQName()); + this.binding = binding; + this.bindingType = TYPE_UNKNOWN; + this.bindingStyle = STYLE_DOCUMENT; + this.hasLiteral = false; + this.attributes = new HashMap(); + this.mimeTypes = new HashMap(); + this.headerParameters = new HashMap(); } // ctor /** @@ -169,6 +213,41 @@ } // setMIMEType /** + * Get the mime mapping for the given parameter name. + * If there is none, this returns null. + */ + public boolean isHeaderParameter(String operationName, + String parameterName) { + Map opMap = (Map) headerParameters.get(operationName); + if (opMap == null) { + return false; + } + else { + Boolean bool = (Boolean) opMap.get(parameterName); + return bool == null ? false : bool.booleanValue(); + } + } // isHeaderParameter + + /** + * Get the header parameter map. + */ + public Map getHeaderParameters() { + return headerParameters; + } // getHeaderParameters + + /** + * Set the header parameter mapping for the given parameter name. + */ + public void setHeaderParameter(String operationName, String parameterName, boolean isHeader) { + Map opMap = (Map) headerParameters.get(operationName); + if (opMap == null) { + opMap = new HashMap(); + headerParameters.put(operationName, opMap); + } + opMap.put(parameterName, new Boolean(isHeader)); + } // setHeaderParameter + + /** * Get this entry's WSDL4J Binding object. */ public Binding getBinding() { @@ -184,6 +263,15 @@ } // getBindingType /** + * Set this entry's binding type. + */ + protected void setBindingType(int bindingType) { + if (bindingType >= TYPE_SOAP && bindingType <= TYPE_UNKNOWN) { + } + this.bindingType = bindingType; + } // setBindingType + + /** * Get this entry's binding style. One of BindingEntry.STYLE_RPC, BindingEntry.STYLE_DOCUMENT. */ public int getBindingStyle() { @@ -191,6 +279,15 @@ } // getBindingStyle /** + * Set this entry's binding style. + */ + protected void setBindingStyle(int bindingStyle) { + if (bindingStyle == STYLE_RPC || bindingStyle == STYLE_DOCUMENT) { + this.bindingStyle = bindingStyle; + } + } // setBindingStyle + + /** * Do any of the message stanzas contain a soap:body which uses literal? */ public boolean hasLiteral() { @@ -198,6 +295,13 @@ } // hasLiteral /** + * Set the literal flag. + */ + protected void setHasLiteral(boolean hasLiteral) { + this.hasLiteral = hasLiteral; + } // setHashLiteral + + /** * Get the input body type for the given operation. One of BindingEntry.USE_ENCODED, * BindingEntry.USE_LITERAL. */ @@ -212,6 +316,21 @@ } // getInputBodyType /** + * Set the input body type for the given operation. + */ + protected void setInputBodyType(Operation operation, int inputBodyType) { + OperationAttr attr = (OperationAttr) attributes.get(operation); + if (attr == null) { + attr = new OperationAttr(); + attributes.put(operation, attr); + } + attr.setInputBodyType(inputBodyType); + if (inputBodyType == USE_LITERAL) { + setHasLiteral(true); + } + } // setInputBodyType + + /** * Get the output body type for the given operation. One of BindingEntry.USE_ENCODED, * BindingEntry.USE_LITERAL. */ @@ -226,6 +345,35 @@ } // getOutputBodyType /** + * Set the output body type for the given operation. + */ + protected void setOutputBodyType(Operation operation, int outputBodyType) { + OperationAttr attr = (OperationAttr) attributes.get(operation); + if (attr == null) { + attr = new OperationAttr(); + attributes.put(operation, attr); + } + attr.setOutputBodyType(outputBodyType); + if (outputBodyType == USE_LITERAL) { + setHasLiteral(true); + } + } // setOutputBodyType + + /** + * Set the body type for the given operation. If input is true, + * then this is the inputBodyType, otherwise it's the outputBodyType. + * (NOTE: this method exists to enable reusing some SymbolTable code. + */ + protected void setBodyType(Operation operation, int bodyType, boolean input) { + if (input) { + setInputBodyType(operation, bodyType); + } + else { + setOutputBodyType(operation, bodyType); + } + } // setBodyType + + /** * Get the fault body type for the given fault of the given operation. One of * BindingEntry.USE_ENCODED, BindingEntry.USE_LITERAL. */ @@ -247,6 +395,18 @@ } /** + * Set the fault body type map for the given operation. + */ + protected void setFaultBodyTypeMap(Operation operation, HashMap faultBodyTypeMap) { + OperationAttr attr = (OperationAttr) attributes.get(operation); + if (attr == null) { + attr = new OperationAttr(); + attributes.put(operation, attr); + } + attr.setFaultBodyTypeMap(faultBodyTypeMap); + } // setInputBodyTypeMap + + /** * Contains attributes for Operations * - Body type: encoded or literal */ @@ -261,16 +421,34 @@ this.faultBodyTypeMap = faultBodyTypeMap; } + public OperationAttr() { + this.inputBodyType = USE_ENCODED; + this.outputBodyType = USE_ENCODED; + this.faultBodyTypeMap = null; + } + public int getInputBodyType() { return inputBodyType; } + protected void setInputBodyType(int inputBodyType) { + this.inputBodyType = inputBodyType; + } + public int getOutputBodyType() { return outputBodyType; } + protected void setOutputBodyType(int outputBodyType) { + this.outputBodyType = outputBodyType; + } + public HashMap getFaultBodyTypeMap() { return faultBodyTypeMap; + } + + protected void setFaultBodyTypeMap(HashMap faultBodyTypeMap) { + this.faultBodyTypeMap = faultBodyTypeMap; } } // class OperationAttr 1.4 +12 -1 xml-axis/java/src/org/apache/axis/wsdl/symbolTable/Parameter.java Index: Parameter.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/symbolTable/Parameter.java,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- Parameter.java 24 Jul 2002 16:15:03 -0000 1.3 +++ Parameter.java 2 Oct 2002 18:21:29 -0000 1.4 @@ -79,11 +79,14 @@ private TypeEntry type; private byte mode = IN; + private boolean inHeader = false; + public String toString() { return "(" + type + (mimeType == null ? "" : "(" + mimeType + ")") + ", " + getName() + ", " - + (mode == IN ? "IN)" : mode == INOUT ? "INOUT)" : "OUT)"); + + (mode == IN ? "IN)" : mode == INOUT ? "INOUT)" : "OUT)" + + (inHeader ? "(soap:header)" : "")); } // toString public QName getQName() { @@ -130,4 +133,12 @@ public void setMode(byte mode) { this.mode = mode; } + + public boolean inHeader() { + return inHeader; + } // inHeader + + public void setInHeader(boolean inHeader) { + this.inHeader = inHeader; + } // setInHeader } // class Parameter 1.42 +89 -76 xml-axis/java/src/org/apache/axis/wsdl/symbolTable/SymbolTable.java Index: SymbolTable.java =================================================================== RCS file: /home/cvs/xml-axis/java/src/org/apache/axis/wsdl/symbolTable/SymbolTable.java,v retrieving revision 1.41 retrieving revision 1.42 diff -u -r1.41 -r1.42 --- SymbolTable.java 24 Sep 2002 20:29:18 -0000 1.41 +++ SymbolTable.java 2 Oct 2002 18:21:29 -0000 1.42 @@ -100,6 +100,7 @@ import javax.wsdl.extensions.http.HTTPBinding; import javax.wsdl.extensions.soap.SOAPBinding; import javax.wsdl.extensions.soap.SOAPBody; +import javax.wsdl.extensions.soap.SOAPHeader; import javax.xml.rpc.holders.BooleanHolder; import javax.xml.rpc.holders.IntHolder; @@ -1259,6 +1260,10 @@ BindingEntry bindingEntry) throws IOException { + // HACK ALERT! This whole method is waaaay too complex. + // It needs rewriting (for instance, we sometimes new up + // a Parameter, then ignore it in favor of another we new up.) + // Determine if there's only one element. For wrapped // style, we normally only have 1 part which is an // element. But with MIME we could have any number of @@ -1326,6 +1331,10 @@ } setMIMEType(param, bindingEntry == null ? null : bindingEntry.getMIMEType(opName, partName)); + if (bindingEntry != null && + bindingEntry.isHeaderParameter(opName, partName)) { + param.setInHeader(true); + } v.add(param); @@ -1406,6 +1415,9 @@ p.setType(elem.getType()); setMIMEType(p, bindingEntry == null ? null : bindingEntry.getMIMEType(opName, partName)); + if (bindingEntry.isHeaderParameter(opName, partName)) { + p.setInHeader(true); + } v.add(p); } } else { @@ -1421,6 +1433,9 @@ } setMIMEType(param, bindingEntry == null ? null : bindingEntry.getMIMEType(opName, partName)); + if (bindingEntry.isHeaderParameter(opName, partName)) { + param.setInHeader(true); + } v.add(param); } @@ -1462,38 +1477,43 @@ private void populateBindings(Definition def) throws IOException { Iterator i = def.getBindings().values().iterator(); while (i.hasNext()) { - int bindingStyle = BindingEntry.STYLE_DOCUMENT; - int bindingType = BindingEntry.TYPE_UNKNOWN; Binding binding = (Binding) i.next(); + + BindingEntry bEntry = new BindingEntry(binding); + symbolTablePut(bEntry); + Iterator extensibilityElementsIterator = binding.getExtensibilityElements().iterator(); while (extensibilityElementsIterator.hasNext()) { Object obj = extensibilityElementsIterator.next(); if (obj instanceof SOAPBinding) { - bindingType = BindingEntry.TYPE_SOAP; + bEntry.setBindingType(BindingEntry.TYPE_SOAP); SOAPBinding sb = (SOAPBinding) obj; String style = sb.getStyle(); if ("rpc".equalsIgnoreCase(style)) { - bindingStyle = BindingEntry.STYLE_RPC; + bEntry.setBindingStyle(BindingEntry.STYLE_RPC); } } else if (obj instanceof HTTPBinding) { HTTPBinding hb = (HTTPBinding) obj; if (hb.getVerb().equalsIgnoreCase("post")) { - bindingType = BindingEntry.TYPE_HTTP_POST; + bEntry.setBindingType(BindingEntry.TYPE_HTTP_POST); } else { - bindingType = BindingEntry.TYPE_HTTP_GET; + bEntry.setBindingType(BindingEntry.TYPE_HTTP_GET); } } } - // Check the Binding Operations for use="literal" - boolean hasLiteral = false; + // Step through the binding operations, setting the following as appropriate: + // - hasLiteral + // - body types + // - mimeTypes + // - headers HashMap attributes = new HashMap(); List bindList = binding.getBindingOperations(); - Map mimeTypes = new HashMap(); for (Iterator opIterator = bindList.iterator(); opIterator.hasNext();) { BindingOperation bindOp = (BindingOperation) opIterator.next(); + Operation operation = bindOp.getOperation(); BindingInput bindingInput = bindOp.getBindingInput(); BindingOutput bindingOutput = bindOp.getBindingOutput(); String opName = bindOp.getName(); @@ -1509,35 +1529,11 @@ new String[] {opName, inputName, outputName})); } - int inputBodyType = BindingEntry.USE_ENCODED; - int outputBodyType = BindingEntry.USE_ENCODED; - Map opMimeTypes = new HashMap(); - mimeTypes.put(opName, opMimeTypes); - // input if (bindingInput != null) { if (bindingInput.getExtensibilityElements() != null) { Iterator inIter = bindingInput.getExtensibilityElements().iterator(); - for (; inIter.hasNext();) { - Object obj = inIter.next(); - if (obj instanceof SOAPBody) { - String use = ((SOAPBody) obj).getUse(); - if (use == null) { - throw new IOException(Messages.getMessage( - "noUse", opName)); - } - if (use.equalsIgnoreCase("literal")) { - inputBodyType = BindingEntry.USE_LITERAL; - } - break; - } - else if (obj instanceof MIMEMultipartRelated) { - IntHolder holder = new IntHolder(inputBodyType); - opMimeTypes.putAll(collectMIMETypes( - (MIMEMultipartRelated) obj, holder, bindOp)); - inputBodyType = holder.value; - } - } + fillInBindingInfo(bEntry, operation, inIter, true); } } @@ -1545,26 +1541,7 @@ if (bindingOutput != null) { if (bindingOutput.getExtensibilityElements() != null) { Iterator outIter = bindingOutput.getExtensibilityElements().iterator(); - for (; outIter.hasNext();) { - Object obj = outIter.next(); - if (obj instanceof SOAPBody) { - String use = ((SOAPBody) obj).getUse(); - if (use == null) { - throw new IOException(Messages.getMessage( - "noUse", opName)); - } - if (use.equalsIgnoreCase("literal")) { - outputBodyType = BindingEntry.USE_LITERAL; - } - break; - } - else if (obj instanceof MIMEMultipartRelated) { - IntHolder holder = new IntHolder(outputBodyType); - opMimeTypes.putAll(collectMIMETypes( - (MIMEMultipartRelated) obj, holder, bindOp)); - outputBodyType = holder.value; - } - } + fillInBindingInfo(bEntry, operation, outIter, false); } } @@ -1597,29 +1574,65 @@ // Add this fault name and bodyType to the map faultMap.put(faultName, new Integer(faultBodyType)); } - // Associate the portType operation that goes with this binding - // with the body types. - attributes.put(bindOp.getOperation(), - new BindingEntry.OperationAttr(inputBodyType, outputBodyType, faultMap)); - - // If the input or output body uses literal, flag the binding as using literal. - // NOTE: should I include faultBodyType in this check? - if (inputBodyType == BindingEntry.USE_LITERAL || - outputBodyType == BindingEntry.USE_LITERAL) { - hasLiteral = true; - } + bEntry.setFaultBodyTypeMap(operation, faultMap); } // binding operations - BindingEntry bEntry = new BindingEntry(binding, bindingType, bindingStyle, hasLiteral, attributes, mimeTypes); - symbolTablePut(bEntry); } } // populateBindings /** - * Collect the list of those parts that are really MIME types. + * Fill in some binding information: bodyType, mimeType, header info. + */ + private void fillInBindingInfo(BindingEntry bEntry, Operation operation, + Iterator it, boolean input) throws IOException { + for (; it.hasNext();) { + Object obj = it.next(); + if (obj instanceof SOAPBody) { + setBodyType(((SOAPBody) obj).getUse(), bEntry, operation, + input); + } + else if (obj instanceof SOAPHeader) { + SOAPHeader header = (SOAPHeader) obj; + setBodyType(header.getUse(), bEntry, operation, input); + + // Note, this only works for explicit headers - those whose + // parts come from messages used in the portType's operation + // input/output clauses - it does not work for implicit + // headers - those whose parts come from messages not used in + // the portType-s operation's input/output clauses. + bEntry.setHeaderParameter(operation.getName(), header.getPart(), + true); + } + else if (obj instanceof MIMEMultipartRelated) { + bEntry.setBodyType(operation, + addMIMETypes(bEntry, (MIMEMultipartRelated) obj, + operation), input); + } + } + } // fillInBindingInfo + + /** + * Set the body type. + */ + private void setBodyType(String use, BindingEntry bEntry, + Operation operation, boolean input) throws IOException { + if (use == null) { + throw new IOException(Messages.getMessage( + "noUse", operation.getName())); + } + if (use.equalsIgnoreCase("literal")) { + bEntry.setBodyType(operation, BindingEntry.USE_LITERAL, + input); + } + } // setBodyType + + /** + * Add the parts that are really MIME types as MIME types. + * A side effect is to return the body Type of the given + * MIMEMultipartRelated object. */ - private Map collectMIMETypes(MIMEMultipartRelated mpr, IntHolder bodyType, - BindingOperation bindOp) throws IOException { - HashMap mimeTypes = new HashMap(); + private int addMIMETypes(BindingEntry bEntry, MIMEMultipartRelated mpr, + Operation op) throws IOException { + int bodyType = BindingEntry.USE_ENCODED; List parts = mpr.getMIMEParts(); Iterator i = parts.iterator(); while (i.hasNext()) { @@ -1630,22 +1643,22 @@ Object obj = j.next(); if (obj instanceof MIMEContent) { MIMEContent content = (MIMEContent) obj; - mimeTypes.put(content.getPart(), content.getType()); + bEntry.setMIMEType(op.getName(), content.getPart(), content.getType()); } else if (obj instanceof SOAPBody) { String use = ((SOAPBody) obj).getUse(); if (use == null) { throw new IOException(Messages.getMessage( - "noUse", bindOp.getName())); + "noUse", op.getName())); } if (use.equalsIgnoreCase("literal")) { - bodyType.value = BindingEntry.USE_LITERAL; + bodyType = BindingEntry.USE_LITERAL; } } } } - return mimeTypes; - } // collectMIMETypes + return bodyType; + } // addMIMETypes /** * Populate the symbol table with all of the ServiceEntry's from the Definition.