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.