You are viewing a plain text version of this content. The canonical link for it is here.
Posted to axis-cvs@ws.apache.org by he...@apache.org on 2003/12/12 08:49:20 UTC

cvs commit: ws-axis/contrib/axismora/src/org/apache/axis/wsdl/toJava Utils.java

hemapani    2003/12/11 23:49:20

  Added:       contrib/axismora/src/org/apache/axis/wsdl/symbolTable
                        ElementDecl.java SchemaUtils.java
               contrib/axismora/src/org/apache/axis/wsdl/toJava Utils.java
  Log:
  These classes are from axis1.1.but thay need be
  changed for WSDL2Ws so I changed them and coimmt them
  to WSDL2Ws(contib) so that they are in the top of the class path
  over the axis.jar and will act just as axis1.1 code changed.
  
  this dependency can replaced after the jaxme code
  is taken in to axis.
  
  Revision  Changes    Path
  1.1                  ws-axis/contrib/axismora/src/org/apache/axis/wsdl/symbolTable/ElementDecl.java
  
  Index: ElementDecl.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.axis.wsdl.symbolTable;
  
  import javax.xml.namespace.QName;
  
  /**
   * Simple utility struct for holding element declarations.
   * 
   * This simply correlates a QName to a TypeEntry.
   * 
   * @author Glen Daniels (gdaniels@apache.org)
   * @author Tom Jordahl (tomj@apache.org)
   */
  public class ElementDecl {
  	private QName name;
  	private TypeEntry type;
  	
  	private int minOccrs = 1;
  	private int maxOccurs = 1;
  	private boolean nillable = false;
  	
  	// The following property is set if minOccurs=0.
  	// An item that is not set and has minOccurs=0 
  	// should not be passed over the wire.  This
  	// is slightly different than nillable=true which
  	// causes nil=true to be passed over the wire.
  	private boolean minOccursIs0=false;   
  
  	// Indicate if the ElementDecl represents
  	// an xsd:any element
  	private boolean anyElement = false;
  
  	public ElementDecl() {
  	}
  
  	public ElementDecl(TypeEntry type, QName name) {
  		this.type = type;
  		this.name = name;
  	}
  
  	public TypeEntry getType() {
  		return type;
  	}
  
  	public void setType(TypeEntry type) {
  		this.type = type;
  	}
  
  	public QName getName() {
  		return name;
  	}
  
  	public void setName(QName name) {
  		this.name = name;
  	}
  
  	public boolean getMinOccursIs0() {
  		return minOccursIs0;
  	}
  
  	public void setMinOccursIs0(boolean minOccursIs0) {
  		this.minOccursIs0 = minOccursIs0;
  	}
  
  	public boolean getAnyElement() {
  		return anyElement;
  	}
  
  	public void setAnyElement(boolean anyElement) {
  		this.anyElement = anyElement;
  	}
      /**
       * @return
       */
      public int getMaxOccurs() {
          return maxOccurs;
      }
  
      /**
       * @return
       */
      public int getMinOccrs() {
          return minOccrs;
      }
  
      /**
       * @return
       */
      public boolean isNillable() {
          return nillable;
      }
  
      /**
       * @param i
       */
      public void setMaxOccurs(int i) {
          maxOccurs = i;
      }
  
      /**
       * @param i
       */
      public void setMinOccrs(int i) {
          minOccrs = i;
      }
  
      /**
       * @param b
       */
      public void setNillable(boolean b) {
          nillable = b;
      }
  
  }
  
  
  
  1.1                  ws-axis/contrib/axismora/src/org/apache/axis/wsdl/symbolTable/SchemaUtils.java
  
  Index: SchemaUtils.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.axis.wsdl.symbolTable;
  
  import org.apache.axis.Constants;
  import org.apache.axismora.wsdl2ws.info.ElementInfo;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  import javax.xml.namespace.QName;
  import javax.xml.rpc.holders.BooleanHolder;
  import javax.xml.rpc.holders.IntHolder;
  import java.util.Arrays;
  import java.util.HashSet;
  import java.util.Set;
  import java.util.Vector;
  
  /**
   * This class contains static utility methods specifically for schema type queries.
   *
   * @author Rich Scheuerle  (scheu@us.ibm.com)
   */
  public class SchemaUtils {
  
  	static final QName VALUE_QNAME = Utils.findQName("", "value");
      
  	/**
  	 * If the specified node represents a supported JAX-RPC complexType or 
  	 * simpleType, a Vector is returned which contains ElementDecls for the 
  	 * child element names. 
  	 * If the element is a simpleType, an ElementDecls is built representing
  	 * the restricted type with the special name "value".
  	 * If the element is a complexType which has simpleContent, an ElementDecl
  	 * is built representing the extended type with the special name "value".
  	 * This method does not return attribute names and types
  	 * (use the getContainedAttributeTypes)
  	 * If the specified node is not a supported 
  	 * JAX-RPC complexType/simpleType/element null is returned.
  	 */
  	public static Vector getContainedElementDeclarations(Node node, SymbolTable symbolTable) {
  		if (node == null) {
  			return null;
  		}
  
  		// If the node kind is an element, dive into it.
  		if (isXSDNode(node, "element")) {
  			NodeList children = node.getChildNodes();
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexType")) {
  					node = kid;
  					break;
  				}
  			}
  		}
  
  		// Expecting a schema complexType or simpleType
  		if (isXSDNode(node, "complexType")) {
  			// Under the complexType there could be complexContent/simpleContent
  			// and extension elements if this is a derived type.  Skip over these.
  			NodeList children = node.getChildNodes();
  			Node complexContent = null;
  			Node simpleContent = null;
  			Node extension = null;
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexContent")) {
  					complexContent = kid;
  					break;      // REMIND: should this be here or on either branch?
  				} else if (isXSDNode(kid, "simpleContent")) {
  					simpleContent = kid;
  				}
  			}
  			if (complexContent != null) {
  				children = complexContent.getChildNodes();
  				for (int j = 0; j < children.getLength() && extension == null; j++) {
  					Node kid = children.item(j);
  					if (isXSDNode(kid, "extension")) { 
  						extension = kid;
  					}
  				}
  			}
  			if (simpleContent != null) {
  				children = simpleContent.getChildNodes();
  				for (int j = 0; j < children.getLength() && extension == null; j++) {
  					QName extensionOrRestrictionKind = Utils.getNodeQName(children.item(j));
  					if (extensionOrRestrictionKind != null &&
  						(extensionOrRestrictionKind.getLocalPart().equals("extension") ||
  						 extensionOrRestrictionKind.getLocalPart().equals("restriction")) &&
  						Constants.isSchemaXSD(extensionOrRestrictionKind.getNamespaceURI())) {
                          
  						// get the type of the extension/restriction from the "base" attribute
  						QName extendsOrRestrictsType =
  							Utils.getTypeQName(children.item(j), new BooleanHolder(), false);
                          
  						// Return an element declaration with a fixed name
  						// ("value") and the correct type.                        
  						Vector v = new Vector();
  						ElementDecl elem = new ElementDecl();
  						elem.setType(symbolTable.getTypeEntry(extendsOrRestrictsType, false));
  						elem.setName(VALUE_QNAME);
  						v.add(elem);
  						return v;
  					}
  				}
  			}
  
  			if (extension != null) {
  				node = extension;  // Skip over complexContent and extension
  			}
  
  			// Under the complexType there may be choice, sequence, group and/or all nodes.      
  			// (There may be other #text nodes, which we will ignore).
  			children = node.getChildNodes();
  			Vector v = new Vector();
  			for (int j = 0; j < children.getLength(); j++) {
  				QName subNodeKind = Utils.getNodeQName(children.item(j));
  				if (subNodeKind != null &&
  					Constants.isSchemaXSD(subNodeKind.getNamespaceURI())) {
  					if (subNodeKind.getLocalPart().equals("sequence")) {
  						v.addAll(processSequenceNode(children.item(j), symbolTable));
  					} else if (subNodeKind.getLocalPart().equals("all")) {
  						v.addAll(processAllNode(children.item(j), symbolTable));
  					} else if (subNodeKind.getLocalPart().equals("choice")) {
  						v.addAll(processChoiceNode(children.item(j), symbolTable));
  					} else if (subNodeKind.getLocalPart().equals("group")) {
  						v.addAll(processGroupNode(children.item(j), symbolTable));
  					}
  				}
  			}
  			return v;
  		} else {
  			// This may be a simpleType, return the type with the name "value"
  			QName simpleQName = getSimpleTypeBase(node);
  			if (simpleQName != null) {
  				TypeEntry simpleType = symbolTable.getType(simpleQName);
  				if (simpleType != null) {
  					Vector v = new Vector();
  					ElementDecl elem = new ElementDecl();
  					elem.setType(simpleType);
  					elem.setName(new javax.xml.namespace.QName("", "value"));
  					v.add(elem);
  					return v;
  				}
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * Invoked by getContainedElementDeclarations to get the child element types
  	 * and child element names underneath a Choice Node
  	 */
  	private static Vector processChoiceNode(Node choiceNode, 
  											SymbolTable symbolTable) {
  		Vector v = new Vector();
  		NodeList children = choiceNode.getChildNodes();
  		for (int j = 0; j < children.getLength(); j++) {
  			QName subNodeKind = Utils.getNodeQName(children.item(j));
  			if (subNodeKind != null &&
  				Constants.isSchemaXSD(subNodeKind.getNamespaceURI())) {
  				if (subNodeKind.getLocalPart().equals("choice")) {
  					v.addAll(processChoiceNode(children.item(j), symbolTable));
  				} else if (subNodeKind.getLocalPart().equals("sequence")) {
  					v.addAll(processSequenceNode(children.item(j), symbolTable));
  				} else if (subNodeKind.getLocalPart().equals("group")) {
  					v.addAll(processGroupNode(children.item(j), symbolTable));
  				} else if (subNodeKind.getLocalPart().equals("element")) {
  					ElementDecl elem = 
  							processChildElementNode(children.item(j), 
  													symbolTable);
  					if (elem != null)
  						v.add(elem);
  				}
  			}
  		}
  		return v;
  	}
  
  	/**
  	 * Invoked by getContainedElementDeclarations to get the child element types
  	 * and child element names underneath a Sequence Node
  	 */
  	private static Vector processSequenceNode(Node sequenceNode, 
  											  SymbolTable symbolTable) {
  		Vector v = new Vector();
  		NodeList children = sequenceNode.getChildNodes();
  		for (int j = 0; j < children.getLength(); j++) {
  			QName subNodeKind = Utils.getNodeQName(children.item(j));
  			if (subNodeKind != null &&
  				Constants.isSchemaXSD(subNodeKind.getNamespaceURI())) {
  				if (subNodeKind.getLocalPart().equals("choice")) {
  					v.addAll(processChoiceNode(children.item(j), symbolTable));
  				} else if (subNodeKind.getLocalPart().equals("sequence")) {
  					v.addAll(processSequenceNode(children.item(j), symbolTable));
  				} else if (subNodeKind.getLocalPart().equals("group")) {
  					v.addAll(processGroupNode(children.item(j), symbolTable));
  				} else if (subNodeKind.getLocalPart().equals("any")) {
  					// Represent this as an element named any of type any type.
  					// This will cause it to be serialized with the element 
  					// serializer.
  					TypeEntry type = symbolTable.getType(Constants.XSD_ANY);
  					ElementDecl elem = 
  						new ElementDecl(type, Utils.findQName("","any"));
  					elem.setAnyElement(true);
  					v.add(elem);
  				} else if (subNodeKind.getLocalPart().equals("element")) {
  					ElementDecl elem = 
  							processChildElementNode(children.item(j), 
  													symbolTable);
  					if (elem != null)
  						v.add(elem);
  				}
  			}
  		}
  		return v;
  	}
  
  	/**
  	 * Invoked by getContainedElementDeclarations to get the child element types
  	 * and child element names underneath a group node.
  	 * (Currently the code only supports a defined group it does not
  	 * support a group that references a previously defined group)
  	 */
  	private static Vector processGroupNode(Node groupNode, SymbolTable symbolTable) {
  		Vector v = new Vector();
  		NodeList children = groupNode.getChildNodes();
  		for (int j = 0; j < children.getLength(); j++) {
  			QName subNodeKind = Utils.getNodeQName(children.item(j));
  			if (subNodeKind != null &&
  				Constants.isSchemaXSD(subNodeKind.getNamespaceURI())) {
  				if (subNodeKind.getLocalPart().equals("choice")) {
  					v.addAll(processChoiceNode(children.item(j), symbolTable));
  				} else if (subNodeKind.getLocalPart().equals("sequence")) {
  					v.addAll(processSequenceNode(children.item(j), symbolTable));
  				} else if (subNodeKind.getLocalPart().equals("all")) {
  					v.addAll(processAllNode(children.item(j), symbolTable));
  				}
  			}
  		}
  		return v;
  	}
  
  	/**
  	 * Invoked by getContainedElementDeclarations to get the child element types
  	 * and child element names underneath an all node.
  	 */
  	private static Vector processAllNode(Node allNode, SymbolTable symbolTable) {
  		Vector v = new Vector();
  		NodeList children = allNode.getChildNodes();
  		for (int j = 0; j < children.getLength(); j++) {
  			Node kid = children.item(j);
  			if (isXSDNode(kid, "element")) {
  				ElementDecl elem = processChildElementNode(kid,symbolTable);
  				if (elem != null) {
  					v.add(elem);
  				}
  			}
  		}
  		return v;
  	}
  
  
  	/**
  	 * Invoked by getContainedElementDeclarations to get the child element type
  	 * and child element name for a child element node.
  	 *
  	 * If the specified node represents a supported JAX-RPC child element,
  	 * we return an ElementDecl containing the child element name and type.
  	 */
  	private static ElementDecl processChildElementNode(Node elementNode, 
  												  SymbolTable symbolTable) {
  		// Get the name qnames.
  		QName nodeName = Utils.getNodeNameQName(elementNode);
  		BooleanHolder forElement = new BooleanHolder();
  
  		// The type qname is used to locate the TypeEntry, which is then
  		// used to retrieve the proper java name of the type.
  		QName nodeType = Utils.getTypeQName(elementNode, forElement, false);
  
  		TypeEntry type = symbolTable.getTypeEntry(nodeType, forElement.value);
  
  		// An element inside a complex type is either qualified or unqualified.
  		// If the ref= attribute is used, the name of the ref'd element is used
  		// (which must be a root element).  If the ref= attribute is not
  		// used, the name of the element is unqualified.
  
  		if (!forElement.value) {
  			// check the Form (or elementFormDefault) attribute of this node to
  			// determine if it should be namespace quailfied or not.
  			String form = Utils.getAttribute(elementNode, "form");
  			if (form != null && form.equals("unqualified")) {
  				// Unqualified nodeName
  				nodeName = Utils.findQName("", nodeName.getLocalPart());            
  			} else if (form == null) {
  				// check elementForDefault on schema element
  				String def = Utils.getScopedAttribute(elementNode, 
  													  "elementFormDefault");
  				if (def == null || def.equals("unqualified")) {
  					// Unqualified nodeName
  					nodeName = Utils.findQName("", nodeName.getLocalPart());            
  				}
  			}
  		}
  
  		if (type != null) {
  			ElementDecl elem = new ElementDecl(type, nodeName);
  			String minOccurs = Utils.getAttribute(elementNode, "minOccurs");
  			if (minOccurs != null && minOccurs.equals("0")) {
  				elem.setMinOccursIs0(true);
  			}
  			if(minOccurs == null){}
  			else if("unbounded".equals(minOccurs))
  				elem.setMinOccrs(ElementInfo.UNBOUNDED);
  			else{	
  				elem.setMinOccrs(Integer.parseInt(minOccurs));
  			}
  
  			
  			String maxOccurs = Utils.getAttribute(elementNode, "maxOccurs");
  			
  			if(maxOccurs == null){}
  			else if("unbounded".equals(maxOccurs))
  				elem.setMaxOccurs(ElementInfo.UNBOUNDED);
  			else	
  				elem.setMaxOccurs(Integer.parseInt(maxOccurs));
  			String nillable = Utils.getAttribute(elementNode, "nilable");
  			if(nillable != null && "true".equals(nillable))
  				elem.setNillable(true);
  			
  			return elem;
  		}
          
  		return null;
  	}
  
  	/**
  	 * Returns the WSDL2Java QName for the anonymous type of the element
  	 * or null.
  	 */
  	public static QName getElementAnonQName(Node node) {
  		if (isXSDNode(node, "element")) {
  			NodeList children = node.getChildNodes();
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexType") || isXSDNode(kid, "simpleType")) {
  					return Utils.getNodeNameQName(kid);
  				}
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * Returns the WSDL2Java QName for the anonymous type of the attribute
  	 * or null.
  	 */
  	public static QName getAttributeAnonQName(Node node) {
  		if (isXSDNode(node, "attribute")) {
  			NodeList children = node.getChildNodes();
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexType") || isXSDNode(kid, "simpleType")) {
  					return Utils.getNodeNameQName(kid);
  				}
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * If the specified node is a simple type or contains simpleContent, return true
  	 */
  	public static boolean isSimpleTypeOrSimpleContent(Node node) {
  		if (node == null) {
  			return false;
  		}
  
  		// If the node kind is an element, dive into it.
  		if (isXSDNode(node, "element")) {
  			NodeList children = node.getChildNodes();
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexType")) {
  					node = kid;
  					break;
  				} else if (isXSDNode(kid, "simpleType")) { 
  					return true;
  				}
  			}
  		}
  
  		// Expecting a schema complexType or simpleType
  		if (isXSDNode(node, "simpleType")) {
  			return true;
  		}
  
  		if (isXSDNode(node, "complexType")) {
  			// Under the complexType there could be complexContent/simpleContent
  			// and extension elements if this is a derived type.  Skip over these.
  			NodeList children = node.getChildNodes();
  			Node complexContent = null;
  			Node simpleContent = null;
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexContent")) {
  					complexContent = kid;
  					break;
  				} else if (isXSDNode(kid, "simpleContent")) {
  					simpleContent = kid;
  				}
  			}
  			if (complexContent != null) {
  				return false;
  			}
  			if (simpleContent != null) {
  				return true;
  			}
  		}
  		return false;
  	}
  
  	/**
  	 * Test whether <tt>node</tt> is not null, belongs to the XML
  	 * Schema namespace, and has a localName that matches
  	 * <tt>schemaLocalName</tt>
  	 *
  	 * This can be used to determine that a given Node defines a
  	 * schema "complexType" "element" and so forth.
  	 *
  	 * @param node a <code>Node</code> value
  	 * @param schemaLocalName a <code>String</code> value
  	 * @return true if the node is matches the name in the schema namespace.
  	 */
  	private static boolean isXSDNode(Node node, String schemaLocalName) {
  		if ((node != null) && Constants.isSchemaXSD(node.getNamespaceURI())) {
  			String localName = node.getLocalName();
  			return ((localName != null) && localName.equals(schemaLocalName));
  		}
  		return false;
  	}
  
  	/**
  	 * If the specified node represents a supported JAX-RPC complexType/element
  	 * which extends another complexType.  The Type of the base is returned.
  	 */
  	public static TypeEntry getComplexElementExtensionBase(Node node, SymbolTable symbolTable) {
  		if (node == null) {
  			return null;
  		}
  
  		TypeEntry cached = (TypeEntry)symbolTable.node2ExtensionBase.get(node);
  		if (cached != null) {
  			return cached;      // cache hit
  		}
  
  		// If the node kind is an element, dive into it.
  		if (isXSDNode(node, "element")) {
  			NodeList children = node.getChildNodes();
  			Node complexNode = null;
  			for (int j = 0; j < children.getLength() && complexNode == null; j++) {
  				if (isXSDNode(children.item(j), "complexType")) {
  					complexNode = children.item(j);
  					node = complexNode;
  				}
  			}
  		}
  
  		// Expecting a schema complexType
  		if (isXSDNode(node, "complexType")) {
  
  			// Under the complexType there could be should be a complexContent &
  			// extension elements if this is a derived type. 
  			NodeList children = node.getChildNodes();
  			Node content = null;
  			Node extension = null;
  			for (int j = 0; j < children.getLength() && content == null; j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) {
  					content = kid;
  				}
  			}
  			if (content != null) {
  				children = content.getChildNodes();
  				for (int j = 0; j < children.getLength() && extension == null; j++) {
  					Node kid = children.item(j);
  					if (isXSDNode(kid, "extension")) {
  						extension = kid;
  					}
  				}
  			}
  			if (extension == null) {
  				cached = null;
  			} else {
  				// Get the QName of the extension base
  				QName extendsType = Utils.getTypeQName(extension, new BooleanHolder(), false);
  				if (extendsType == null) {
  					cached = null;
  				} else {
  					// Return associated Type
  					cached = symbolTable.getType(extendsType);
  				}
  			}
  		}
  		symbolTable.node2ExtensionBase.put(node, cached);
  		return cached;
  	}
  
  	/**
  	 * If the specified node represents a 'normal' non-enumeration simpleType,
  	 * the QName of the simpleType base is returned.
  	 */
  	public static QName getSimpleTypeBase(Node node) {
  		QName baseQName = null;
  
  		if (node == null) {
  			return null;
  		}
  
  		// If the node kind is an element, dive into it.
  		QName nodeKind = Utils.getNodeQName(node);
  		if (isXSDNode(node, "element")) {
  			NodeList children = node.getChildNodes();
  			for (int j = 0; j < children.getLength(); j++) {
  				if (isXSDNode(children.item(j), "simpleType")) {
  					node = children.item(j);
  					break;
  				}
  			}
  		}
  		// Get the node kind, expecting a schema simpleType
  		if (isXSDNode(node, "simpleType")) {
  			// Under the simpleType there should be a restriction.
  			// (There may be other #text nodes, which we will ignore).
  			NodeList children = node.getChildNodes();
  			Node restrictionNode = null;
  			for (int j = 0; j < children.getLength() && restrictionNode == null; j++) {
  				if (isXSDNode(children.item(j), "restriction")) {
  					restrictionNode = children.item(j);
  				}
  			}
  
  			// The restriction node indicates the type being restricted
  			// (the base attribute contains this type).
              
  			if (restrictionNode != null) {
  				baseQName = Utils.getTypeQName(restrictionNode, new BooleanHolder(), false);
  			}
              
  			// Look for enumeration elements underneath the restriction node
  			if (baseQName != null && restrictionNode != null) {
  				NodeList enums = restrictionNode.getChildNodes();
  				for (int i=0; i < enums.getLength(); i++) {
  					if (isXSDNode(enums.item(i), "enumeration")) {
  						// Found an enumeration, this isn't a 
  						// 'normal' simple type.
  						return null;
  					}
  				}
  			}
  		}
  		return baseQName;
  	}
  
  	/**
  	 * Returns the contained restriction or extension node underneath
  	 * the specified node.  Returns null if not found
  	 */
  	public static Node getRestrictionOrExtensionNode(Node node) {
  		Node re = null;
  		if (node == null) {
  			return re;
  		}
  
  		// If the node kind is an element, dive into it.
  		if (isXSDNode(node, "element")) {
  			NodeList children = node.getChildNodes();
  			Node node2 = null;
  			for (int j = 0; j < children.getLength(); j++) {
  				Node n = children.item(j);
  				if (isXSDNode(n, "simpleType") || isXSDNode(n, "complexType") || isXSDNode(n, "simpleContent")) {
  					node = n;
  					break;
  				}
  			}
  		}
  		// Get the node kind, expecting a schema simpleType
  		if (isXSDNode(node, "simpleType") || isXSDNode(node, "complexType")) {
  			// Under the complexType there could be a complexContent.
  			NodeList children = node.getChildNodes();
  			Node complexContent = null;
  			if (node.getLocalName().equals("complexType")) {
  				for (int j = 0; j < children.getLength() && complexContent == null; j++) {
  					Node kid = children.item(j);
  					if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) {
  						complexContent = kid;
  					}
  				}
  				node = complexContent;
  			}
  			// Now get the extension or restriction node
  			if (node != null) {
  				children = node.getChildNodes();
  				for (int j = 0; j < children.getLength() && re == null; j++) {
  					Node kid = children.item(j);
  					if (isXSDNode(kid, "extension") || isXSDNode(kid, "restriction")) {
  						re = kid;
  					}
  				}
  			}
  		}
              
  		return re;
  	}
  
  	/**
  	 * If the specified node represents an array encoding of one of the following
  	 * forms, then return the qname repesenting the element type of the array.
  	 * @param node is the node
  	 * @param dims is the output value that contains the number of dimensions if return is not null
  	 * @return QName or null
  	 */
  	public static QName getArrayComponentQName(Node node, IntHolder dims) {
  		dims.value = 1;  // assume 1 dimension
  		QName qName = getCollectionComponentQName(node);
  		if (qName == null) {
  			qName = getArrayComponentQName_JAXRPC(node, dims);
  		}
  		return qName;
  	}
  
  	/**
  	 * If the specified node represents an element that references a collection
  	 * then return the qname repesenting the component of the collection.
  	 *
  	 *  <xsd:element name="alias" type="xsd:string" maxOccurs="unbounded"/>
  	 *    returns qname for"xsd:string"
  	 *  <xsd:element ref="alias"  maxOccurs="unbounded"/>
  	 *    returns qname for "alias"
  	 * @param node is the Node
  	 * @return QName of the compoent of the collection
  	 */
  	public static QName getCollectionComponentQName(Node node) {
  		if (node == null) {
  			return null;
  		}
  
  		// If the node kind is an element, dive get its type.
  		if (isXSDNode(node, "element")) {
  			// Compare the componentQName with the name of the
  			// full name.  If different, return componentQName
  			BooleanHolder forElement = new BooleanHolder();
  			QName componentQName = Utils.getTypeQName(node, forElement, true);
  			if (componentQName != null) {
  				QName fullQName = Utils.getTypeQName(node, forElement, false);
  				if (!componentQName.equals(fullQName)) {
  					return componentQName;
  				}
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * If the specified node represents an array encoding of one of the following
  	 * forms, then return the qname repesenting the element type of the array.
  	 *
  	 * @param node is the node
  	 * @param dims is the output value that contains the number of dimensions if return is not null
  	 * @return QName or null
  	 *
  	 * JAX-RPC Style 2:
  	 *<xsd:complexType name="hobbyArray">
  	 *  <xsd:complexContent>
  	 *    <xsd:restriction base="soapenc:Array">
  	 *      <xsd:attribute ref="soapenc:arrayType" wsdl:arrayType="xsd:string[]"/>
  	 *    </xsd:restriction>
  	 *  </xsd:complexContent>
  	 *</xsd:complexType>
  	 *
  	 * JAX-RPC Style 3:
  	 *<xsd:complexType name="petArray">
  	 *  <xsd:complexContent>
  	 *    <xsd:restriction base="soapenc:Array">
  	 *      <xsd:sequence>
  	 *        <xsd:element name="alias" type="xsd:string" maxOccurs="unbounded"/>
  	 *      </xsd:sequence>
  	 *    </xsd:restriction>
  	 *  </xsd:complexContent>
  	 *</xsd:complexType>
  	 *
  	 */
  	private static QName getArrayComponentQName_JAXRPC(Node node, IntHolder dims) {
  		dims.value = 0;  // Assume 0
  		if (node == null) {
  			return null;
  		}
  
  		// If the node kind is an element, dive into it.
  		if (isXSDNode(node, "element")) {
  			NodeList children = node.getChildNodes();
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexType")) {
  					node = kid;
  					break;
  				}
  			}
  		}
  
  		// Get the node kind, expecting a schema complexType
  		if (isXSDNode(node, "complexType")) {
  			// Under the complexType there should be a complexContent.
  			// (There may be other #text nodes, which we will ignore).
  			NodeList children = node.getChildNodes();
  			Node complexContentNode = null;
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) {
  					complexContentNode = kid;
  					break;
  				}
  			}
  
  			// Under the complexContent there should be a restriction.
  			// (There may be other #text nodes, which we will ignore).
  			Node restrictionNode = null;
  			if (complexContentNode != null) {
  				children = complexContentNode.getChildNodes();
  				for (int j = 0; j < children.getLength(); j++) {
  					Node kid = children.item(j);
  					if (isXSDNode(kid, "restriction")) {
  						restrictionNode = kid;
  						break;
  					}
  				}
  			}
  
  			// The restriction node must have a base of soapenc:Array.              
  			QName baseType = null;
  			if (restrictionNode != null) {
  				baseType = Utils.getTypeQName(restrictionNode, new BooleanHolder(), false);
  				if (baseType != null &&
  					baseType.getLocalPart().equals("Array") &&
  					Constants.isSOAP_ENC(baseType.getNamespaceURI()))
  					; // Okay
  				else
  					baseType = null;  // Did not find base=soapenc:Array
  			}
  
              
  			// Under the restriction there should be an attribute OR a sequence/all group node.
  			// (There may be other #text nodes, which we will ignore).
  			Node groupNode = null;
  			Node attributeNode = null;
  			if (baseType != null) {
  				children = restrictionNode.getChildNodes();
  				for (int j = 0;
  					 j < children.getLength() && groupNode == null && attributeNode == null;
  					 j++) {
  					Node kid = children.item(j);
  					if (isXSDNode(kid, "sequence") || isXSDNode(kid, "all")) {
  						groupNode = kid;
  						if (groupNode.getChildNodes().getLength() == 0) {
  							// This covers the rather odd but legal empty sequence.
  							// <complexType name="ArrayOfString">
  							//   <complexContent>
  							//     <restriction base="soapenc:Array">
  							//       <sequence/>
  							//       <attribute ref="soapenc:arrayType" wsdl:arrayType="string[]"/>
  							//     </restriction>
  							//   </complexContent>
  							// </complexType>
  							groupNode = null;
  						}
  					}
  					if (isXSDNode(kid, "attribute")) {
  						// If the attribute node does not have ref="soapenc:arrayType"
  						// then keep looking.
  						BooleanHolder isRef = new BooleanHolder();
  						QName refQName = Utils.getTypeQName(kid, isRef, false);
  						if (refQName != null &&
  							isRef.value &&
  							refQName.getLocalPart().equals("arrayType") &&
  							Constants.isSOAP_ENC(refQName.getNamespaceURI())) {
  							attributeNode = kid;
  						}
  					}
  				}
  			}
  
  			// If there is an attribute node, look at wsdl:arrayType to get the element type
  			if (attributeNode != null) {
  				String wsdlArrayTypeValue = null;
  				Vector attrs = Utils.getAttributesWithLocalName(attributeNode, "arrayType");
  				for (int i=0; i < attrs.size() && wsdlArrayTypeValue == null; i++) {
  					Node attrNode = (Node) attrs.elementAt(i);
  					String attrName = attrNode.getNodeName();
  					QName attrQName = Utils.getQNameFromPrefixedName(attributeNode, attrName);
  					if (Constants.isWSDL(attrQName.getNamespaceURI())) {
  						wsdlArrayTypeValue = attrNode.getNodeValue();
  					}
  				}
  
  				// The value could have any number of [] or [,] on the end
  				// Strip these off to get the prefixed name.
  				// The convert the prefixed name into a qname.
  				// Count the number of [ and , to get the dim information.
  				if (wsdlArrayTypeValue != null) {
  					int i = wsdlArrayTypeValue.indexOf('[');
  					if (i > 0) {
  						String prefixedName = wsdlArrayTypeValue.substring(0,i);
  						String mangledString = wsdlArrayTypeValue.replace(',', '[');
  						dims.value = 0;
  						int index = mangledString.indexOf('[');
  						while (index > 0) {
  							dims.value++;
  							index = mangledString.indexOf('[',index+1);
  						}
                          
  						return Utils.getQNameFromPrefixedName(restrictionNode, prefixedName);
  					}
  				}
  			} else if (groupNode != null) {
  
  				// Get the first element node under the group node.       
  				NodeList elements = groupNode.getChildNodes();
  				Node elementNode = null;
  				for (int i=0; i < elements.getLength() && elementNode == null; i++) {
  					Node kid = elements.item(i);
  					if (isXSDNode(kid, "element")) {
  						elementNode = elements.item(i);
  						break;
  					}
  				}
                   
  				// The element node should have maxOccurs="unbounded" and
  				// a type
  				if (elementNode != null) {
  					String maxOccursValue = Utils.getAttribute(elementNode, "maxOccurs");
  					if (maxOccursValue != null &&
  						maxOccursValue.equalsIgnoreCase("unbounded")) {
  						// Get the QName of the type without considering maxOccurs
  						dims.value = 1;
  						return Utils.getTypeQName(elementNode, new BooleanHolder(), true);
  					}
  				}
  			}
              
  		}
  		return null;
  	}
  
  	/**
  	 * Return the attribute names and types if any in the node
  	 * The even indices are the element types (TypeEntry) and
  	 * the odd indices are the corresponding names (Strings).
  	 * 
  	 * Example:
  	 * <complexType name="Person">
  	 *   <sequence>
  	 *     <element minOccurs="1" maxOccurs="1" name="Age" type="double" />
  	 *     <element minOccurs="1" maxOccurs="1" name="ID" type="xsd:float" />
  	 *   </sequence>
  	 *   <attribute name="Name" type="string" />
  	 *   <attribute name="Male" type="boolean" />
  	 * </complexType>
  	 * 
  	 */ 
  	public static Vector getContainedAttributeTypes(Node node, 
  													SymbolTable symbolTable) 
  	{
  		Vector v = null;    // return value
          
  		if (node == null) {
  			return null;
  		}
  		// Check for SimpleContent
  		// If the node kind is an element, dive into it.
  		if (isXSDNode(node, "element")) {
  			NodeList children = node.getChildNodes();
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexType")) {
  					node = kid;
  					break;
  				}
  			}
  		}
  
  		// Expecting a schema complexType
  		if (isXSDNode(node, "complexType")) {
  			// Under the complexType there could be complexContent/simpleContent
  			// and extension elements if this is a derived type.  Skip over these.
  			NodeList children = node.getChildNodes();
  			Node content = null;
  			for (int j = 0; j < children.getLength(); j++) {
  				Node kid = children.item(j);
  				if (isXSDNode(kid, "complexContent") || isXSDNode(kid, "simpleContent")) {
  					content = kid;
  					break;
  				}
  			}
  			// Check for extensions
  			if (content != null) {
  				children = content.getChildNodes();
  				for (int j = 0; j < children.getLength(); j++) {
  					Node kid = children.item(j);
  					if (isXSDNode(kid, "extension")) {
  						node = kid;
  						break;
  					}
  				}
  			}
              
  			// examine children of the node for <attribute> elements
  			children = node.getChildNodes();
  			for (int i = 0; i < children.getLength(); i++) {
  				Node child = children.item(i);
  				if (! isXSDNode(child, "attribute")) {
  					continue;
  				}
                  
  				// we have an attribute node
  				if (v == null)
  					v = new Vector();
  
  				// Get the name and type qnames.
  				// The type qname is used to locate the TypeEntry, which is then
  				// used to retrieve the proper java name of the type.
  				QName attributeName = Utils.getNodeNameQName(child);
  				BooleanHolder forElement = new BooleanHolder();
  				QName attributeType = Utils.getTypeQName(child, forElement, false);
  
  				// An attribute is either qualified or unqualified.
  				// If the ref= attribute is used, the name of the ref'd element is used
  				// (which must be a root element).  If the ref= attribute is not
  				// used, the name of the attribute is unqualified.
  				if (!forElement.value) {
  					// check the Form (or attributeFormDefault) attribute of 
  					// this node to determine if it should be namespace 
  					// quailfied or not.
  					String form = Utils.getAttribute(child, "form");
  					if (form != null && form.equals("unqualified")) {
  						// Unqualified nodeName
  						attributeName = Utils.findQName("", attributeName.getLocalPart());            
  					} else if (form == null) {
  						// check attributeFormDefault on schema element
  						String def = Utils.getScopedAttribute(child, 
  															  "attributeFormDefault");
  						if (def == null || def.equals("unqualified")) {
  							// Unqualified nodeName
  							attributeName = Utils.findQName("", attributeName.getLocalPart());            
  						}
  					}
  				} else {
  					attributeName = attributeType;
  				}
                  
  				// Get the corresponding TypeEntry from the symbol table
  				TypeEntry type = symbolTable.getTypeEntry(attributeType, 
  														  forElement.value);
                  
  				// add type and name to vector, skip it if we couldn't parse it
  				// XXX - this may need to be revisited.
  				if (type != null && attributeName != null) {
  					v.add(type);
  					v.add(attributeName);
  				}
  			}
  		}            
  		return v;
  	}
  
  	// list of all of the XSD types in Schema 2001
  	private static String schemaTypes[] = {
  		"string",
  		"normalizedString",
  		"token",        
  		"byte",
  		"unsignedByte",
  		"base64Binary",
  		"hexBinary",    
  		"integer",
  		"positiveInteger",
  		"negativeInteger",
  		"nonNegativeInteger",
  		"nonPositiveInteger",
  		"int",
  		"unsignedInt",  
  		"long",
  		"unsignedLong",
  		"short",
  		"unsignedShort",
  		"decimal",
  		"float",
  		"double",
  		"boolean",
  		"time",
  		"dateTime",
  		"duration",
  		"date",
  		"gMonth",
  		"gYear",
  		"gYearMonth",
  		"gDay",
  		"gMonthDay",
  		"Name",
  		"QName",
  		"NCName",
  		"anyURI",
  		"language",
  		"ID",
  		"IDREF",
  		"IDREFS",
  		"ENTITY",
  		"ENTITIES",
  		"NOTATION",
  		"NMTOKEN",
  		"NMTOKENS"
  	};
  
  	private static final Set schemaTypeSet = new HashSet(Arrays.asList(schemaTypes));
      
  	/**
  	 * Determine if a string is a simple XML Schema type 
  	 */ 
  	private static boolean isSimpleSchemaType(String s) {
  		if (s == null)
  			return false;
  
  		return schemaTypeSet.contains(s);
  	}
  	/**
  	 * Determine if a QName is a simple XML Schema type 
  	 */ 
  	public static boolean isSimpleSchemaType(QName qname) {
  		if (qname == null || 
  			!Constants.isSchemaXSD(qname.getNamespaceURI())) {
  			return false;
  		}
  		return isSimpleSchemaType(qname.getLocalPart());
  	}
  }
  
  
  
  1.1                  ws-axis/contrib/axismora/src/org/apache/axis/wsdl/toJava/Utils.java
  
  Index: Utils.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   *
   * Copyright (c) 2001-2003 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Axis" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  package org.apache.axis.wsdl.toJava;
  
  import org.apache.axis.Constants;
  import org.apache.axis.enum.Style;
  import org.apache.axis.utils.JavaUtils;
  import org.apache.axis.wsdl.symbolTable.BindingEntry;
  import org.apache.axis.wsdl.symbolTable.CollectionTE;
  import org.apache.axis.wsdl.symbolTable.Element;
  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.SchemaUtils;
  import org.apache.axis.wsdl.symbolTable.SymbolTable;
  import org.apache.axis.wsdl.symbolTable.TypeEntry;
  import org.apache.axis.wsdl.symbolTable.MimeInfo;
  import org.w3c.dom.Node;
  import org.w3c.dom.NodeList;
  
  import javax.wsdl.BindingInput;
  import javax.wsdl.BindingOperation;
  import javax.wsdl.Input;
  import javax.wsdl.Message;
  import javax.wsdl.Operation;
  import javax.wsdl.Part;
  import javax.wsdl.extensions.ExtensibilityElement;
  import javax.wsdl.extensions.UnknownExtensibilityElement;
  import javax.wsdl.extensions.mime.MIMEMultipartRelated;
  import javax.wsdl.extensions.soap.SOAPBody;
  import javax.xml.namespace.QName;
  import javax.xml.rpc.holders.BooleanHolder;
  import java.io.File;
  import java.io.IOException;
  import java.net.MalformedURLException;
  import java.net.URL;
  import java.util.HashMap;
  import java.util.Iterator;
  import java.util.List;
  import java.util.Map;
  import java.util.StringTokenizer;
  import java.util.Vector;
  
  public class Utils extends org.apache.axis.wsdl.symbolTable.Utils {
  	/**
  	 * Given a type, return the Java mapping of that type's holder.
  	 */
  	public static String holder(MimeInfo mimeInfo, TypeEntry type, Emitter emitter) {
  		String mimeType = mimeInfo == null ? null : mimeInfo.getType();
  		String mimeDimensions = mimeInfo == null ? "" : mimeInfo.getDimensions();
  
  		// Add the holders that JAX-RPC forgot about - the MIME type holders.
  		if (mimeType != null) {
  			if (mimeType.equals("image/gif") ||
  				mimeType.equals("image/jpeg")) {
  				return "org.apache.axis.holders.ImageHolder" + mimeDimensions;
  			}
  			else if (mimeType.equals("text/plain")) {
  				return "javax.xml.rpc.holders.StringHolder" + mimeDimensions;
  			}
  			else if (mimeType.startsWith("multipart/")) {
  				return "org.apache.axis.holders.MimeMultipartHolder" + mimeDimensions;
  			}
  			else if (mimeType.startsWith("application/octetstream")
  					|| mimeType.startsWith("application/octet-stream")) {
  				return "org.apache.axis.holders.OctetStreamHolder" + mimeDimensions;
  			}
  			else if (mimeType.equals("text/xml") ||
  					 mimeType.equals("application/xml")) {
  				return "org.apache.axis.holders.SourceHolder" + mimeDimensions;
  			}
  		}
  
  		String typeValue = type.getName();
  
  		// byte[] has a reserved holders
  		if (typeValue.equals("byte[]")) {
  			return "javax.xml.rpc.holders.ByteArrayHolder";
  		}
  		// Anything else with [] gets its holder from the qname
  		else if (typeValue.endsWith("[]")) {
  			String name = emitter.getJavaName(type.getQName());
  			// This could be a special QName for a indexed property.
  			// If so, change the [] to Array.
  			name = JavaUtils.replace(name, "[]", "Array");
  			name = addPackageName(name, "holders");
  			return name + "Holder";
  		}
  		// String also has a reserved holder
  		else if (typeValue.equals("String")) {
  			return "javax.xml.rpc.holders.StringHolder";
  		}
  		else if (typeValue.equals("java.lang.String")) {
  			return "javax.xml.rpc.holders.StringHolder";
  		}
  		// Object also has a reserved holder
  		else if (typeValue.equals("Object")) {
  			return "javax.xml.rpc.holders.ObjectHolder";
  		}
  		else if (typeValue.equals("java.lang.Object")) {
  			return "javax.xml.rpc.holders.ObjectHolder";
  		}
  		// Java primitive types have reserved holders
  		else if (typeValue.equals("int")
  				 || typeValue.equals("long")
  				 || typeValue.equals("short")
  				 || typeValue.equals("float")
  				 || typeValue.equals("double")
  				 || typeValue.equals("boolean")
  				 || typeValue.equals("byte")) {
  			return "javax.xml.rpc.holders." + capitalizeFirstChar(typeValue) + "Holder";
  		}
  		// Java language classes have reserved holders (with ClassHolder)
  		else if (typeValue.startsWith("java.lang.")) {
  			return "javax.xml.rpc.holders" + 
  				typeValue.substring(typeValue.lastIndexOf(".")) +
  				"WrapperHolder";
  		}
  		else if (typeValue.indexOf(".") < 0) {
  			return "javax.xml.rpc.holders" + 
  				typeValue +
  				"WrapperHolder";
  		}
  		// The classes have reserved holders because they 
  		// represent schema/soap encoding primitives
  		else if (typeValue.equals("java.math.BigDecimal")) {
  			return "javax.xml.rpc.holders.BigDecimalHolder";
  		}
  		else if (typeValue.equals("java.math.BigInteger")) {
  			return "javax.xml.rpc.holders.BigIntegerHolder";
  		}
  		else if  (typeValue.equals("java.util.Date")) {
  			return "org.apache.axis.holders.DateHolder";
  		}
  		else if (typeValue.equals("java.util.Calendar")) {
  			return "javax.xml.rpc.holders.CalendarHolder";
  		}
  		else if (typeValue.equals("javax.xml.namespace.QName")) {
  			return "javax.xml.rpc.holders.QNameHolder";
  		}
  		else if (typeValue.equals("javax.activation.DataHandler")) {
  			return "org.apache.axis.holders.DataHandlerHolder";
  		}
  		// Check for Axis specific types and return their holders
  		else if (typeValue.startsWith("org.apache.axis.types.")) {
  			int i = typeValue.lastIndexOf('.');
  			String t = typeValue.substring(i+1);
  			return "org.apache.axis.holders." + t + "Holder";
  		}
  		// For everything else add "holders" package and append
  		// holder to the class name.
  		else {
  			return addPackageName(typeValue, "holders") + "Holder";
  		}
  	} // holder
  
  	/**
  	 * Add package to name
  	 * @param className full name of the class.
  	 * @param newPkg name of the package to append
  	 * @return String name with package name added
  	 */
  	public static String addPackageName(String className, String newPkg) {
  		int index = className.lastIndexOf(".");
  		if (index >= 0) {
  			return className.substring(0, index)
  				+ "." + newPkg
  				+ className.substring(index);
  		} else {
  			return newPkg + "." + className;
  		}
  	}
  
  	/**
  	 * Given a fault message, return the fully qualified Java class name
  	 * of the exception to be generated from this fault
  	 * 
  	 * @param faultMessage The WSDL fault message
  	 * @param symbolTable the current symbol table
  	 * @return A Java class name for the fault
  	 */ 
  	public static String getFullExceptionName(Message faultMessage, 
  											  SymbolTable symbolTable) {
  		MessageEntry me = symbolTable.getMessageEntry(faultMessage.getQName()); 
  		return (String) me.getDynamicVar(JavaGeneratorFactory.EXCEPTION_CLASS_NAME);
  	} // getFullExceptionName
  
  	/**
  	 * Given a fault message, return the XML type of the exception data.
  	 * 
  	 * @param faultMessage The WSDL fault message object
  	 * @param symbolTable the current symbol table
  	 * @return A QName for the XML type of the data
  	 */ 
  	public static QName getFaultDataType(Message faultMessage, 
  										 SymbolTable symbolTable) {
  		MessageEntry me = symbolTable.getMessageEntry(faultMessage.getQName()); 
  		return (QName) me.getDynamicVar(JavaGeneratorFactory.EXCEPTION_DATA_TYPE);
  	} // getFaultDataType
  
  	/**
  	 * Given a fault message, return TRUE if the fault is a complex type fault
  	 * 
  	 * @param faultMessage The WSDL fault message object
  	 * @param symbolTable the current symbol table
  	 * @return A Java class name for the fault
  	 */ 
  	public static boolean isFaultComplex(Message faultMessage, 
  										 SymbolTable symbolTable) {
  		MessageEntry me = symbolTable.getMessageEntry(faultMessage.getQName()); 
  		Boolean ret = (Boolean) me.getDynamicVar(JavaGeneratorFactory.COMPLEX_TYPE_FAULT);
  		if (ret != null) {
  			return ret.booleanValue();
  		} else {
  			return false;
  		}
  	} // isFaultComplex
  
  	/**
  	 * If the specified node represents a supported JAX-RPC enumeration,
  	 * a Vector is returned which contains the base type and the enumeration values.
  	 * The first element in the vector is the base type (an TypeEntry).
  	 * Subsequent elements are values (Strings).
  	 * If this is not an enumeration, null is returned.
  	 */
  	public static Vector getEnumerationBaseAndValues(Node node, SymbolTable symbolTable) {
  		if (node == null) {
  			return null;
  		}
  
  		// If the node kind is an element, dive into it.
  		QName nodeKind = Utils.getNodeQName(node);
  		if (nodeKind != null &&
  			nodeKind.getLocalPart().equals("element") &&
  			Constants.isSchemaXSD(nodeKind.getNamespaceURI())) {
  			NodeList children = node.getChildNodes();
  			Node simpleNode = null;
  			for (int j = 0; j < children.getLength() && simpleNode == null; j++) {
  				QName simpleKind = Utils.getNodeQName(children.item(j));
  				if (simpleKind != null &&
  					simpleKind.getLocalPart().equals("simpleType") &&
  					Constants.isSchemaXSD(simpleKind.getNamespaceURI())) {
  					simpleNode = children.item(j);
  					node = simpleNode;
  				}
  			}
  		}
  		// Get the node kind, expecting a schema simpleType
  		nodeKind = Utils.getNodeQName(node);
  		if (nodeKind != null &&
  			nodeKind.getLocalPart().equals("simpleType") &&
  			Constants.isSchemaXSD(nodeKind.getNamespaceURI())) {
  
  			// Under the simpleType there should be a restriction.
  			// (There may be other #text nodes, which we will ignore).
  			NodeList children = node.getChildNodes();
  			Node restrictionNode = null;
  			for (int j = 0; j < children.getLength() && restrictionNode == null; j++) {
  				QName restrictionKind = Utils.getNodeQName(children.item(j));
  				if (restrictionKind != null &&
  					restrictionKind.getLocalPart().equals("restriction") &&
  					Constants.isSchemaXSD(restrictionKind.getNamespaceURI()))
  					restrictionNode = children.item(j);
  			}
  
  			// The restriction node indicates the type being restricted
  			// (the base attribute contains this type).
  			// The base type must be a simple type, and not boolean
  			TypeEntry baseEType = null;
  			if (restrictionNode != null) {
  				QName baseType = Utils.getTypeQName(restrictionNode, new BooleanHolder(), false);
  				baseEType = symbolTable.getType(baseType);
  				if (baseEType != null) {
  					String javaName = baseEType.getName();
  					if ("boolean".equals(javaName) ||
  						! SchemaUtils.isSimpleSchemaType(baseEType.getQName())) {
  						baseEType = null;
  					}
  				}
  			}
  
  			// Process the enumeration elements underneath the restriction node
  			if (baseEType != null && restrictionNode != null) {
  
  				Vector v = new Vector();                
  				NodeList enums = restrictionNode.getChildNodes();
  				for (int i=0; i < enums.getLength(); i++) {
  					QName enumKind = Utils.getNodeQName(enums.item(i));
  					if (enumKind != null &&
  						enumKind.getLocalPart().equals("enumeration") &&
  						Constants.isSchemaXSD(enumKind.getNamespaceURI())) {
  
  						// Put the enum value in the vector.
  						Node enumNode = enums.item(i);
  						String value = Utils.getAttribute(enumNode, "value");
  						if (value != null) {
  							v.add(value);
  						}
  					}
  				}
                  
  				// is this really an enumeration?
  				if(v.isEmpty()) return null;
                  
  				// The first element in the vector is the base type (an TypeEntry).
  				v.add(0,baseEType);
  				return v;
  			}
  		}
  		return null;
  	}
  
  	/**
  	 * Capitalize the first character of the name.
  	 */
  	public static String capitalizeFirstChar(String name) {
  		if (name == null || name.equals(""))
  			return name;
          
  		char start = name.charAt(0);
  
  		if (Character.isLowerCase(start)) {
  			start = Character.toUpperCase(start);
  			return start + name.substring(1);
  		}
  		return name;
  	} // capitalizeFirstChar
  
  	/**
  	 * Prepend an underscore to the name
  	 */
  	public static String addUnderscore(String name) {
  	  if (name == null || name.equals(""))
  		  return name;
  	  return "_" + name;
  	}
  
  	/**
  	 * Map an XML name to a valid Java identifier
  	 */
  	public static String xmlNameToJava(String name)
  	{
  		// NOTE:  This method should really go away and all callers should call
  		// JavaUtils.xmlNameToJava directly.  But there are a lot of them and I wanted
  		// to keep the changes to a minimum.  Besides, these are static methods so the should
  		// be inlined.
  		return JavaUtils.xmlNameToJava(name);
  	}
  
  	/**
  	 * Map an XML name to a valid Java identifier w/ capitolized first letter 
  	 */ 
  	public static String xmlNameToJavaClass(String name)
  	{
  		return capitalizeFirstChar(xmlNameToJava(name));
  	}
  
  	public static String makePackageName(String namespace)
  	{
  		String hostname = null;
  		String path = "";
  
  		// get the target namespace of the document
  		try {
  			URL u = new URL(namespace);
  			hostname = u.getHost();
  			path = u.getPath();
  		}
  		catch (MalformedURLException e) {
  			if (namespace.indexOf(":") > -1) {
  				hostname = namespace.substring(namespace.indexOf(":") + 1);
  				if (hostname.indexOf("/") > -1)
  					hostname = hostname.substring(0, hostname.indexOf("/") );
  			}
  			else {
  				hostname = namespace;
  			}
  		}
  
  		// if we didn't file a hostname, bail
  		if (hostname == null) {
  			return null;
  		}
  
  		//convert illegal java identifier
  		hostname = hostname.replace('-', '_');
  		path = path.replace('-', '_');
          
  		// chomp off last forward slash in path, if necessary
  		if (path.length() > 0 && path.charAt(path.length() - 1) == '/') {
  			path = path.substring(0, path.length() - 1);
  		}
  
  		// tokenize the hostname and reverse it
  		StringTokenizer st = new StringTokenizer( hostname, ".:" );
  		String[] words = new String[ st.countTokens() ];
  		for(int i = 0; i < words.length; ++i)
  			words[i] = st.nextToken();
  
  		StringBuffer sb = new StringBuffer(namespace.length());
  		for(int i = words.length-1; i >= 0; --i) {
  			addWordToPackageBuffer(sb, words[i], (i == words.length -1));
  		}
  
  		// tokenize the path
  		StringTokenizer st2 = new StringTokenizer( path, "/" );
  		while (st2.hasMoreTokens()) {
  			addWordToPackageBuffer(sb, st2.nextToken(), false);
  		}
  		return sb.toString();
  	}
  
  	/**
  	 * Massage <tt>word</tt> into a form suitable for use in a Java package name.
  	 * Append it to the target string buffer with a <tt>.</tt> delimiter iff
  	 * <tt>word</tt> is not the first word in the package name.
  	 * 
  	 * @param sb the buffer to append to
  	 * @param word the word to append
  	 * @param firstWord a flag indicating whether this is the first word
  	 */
  	private static void addWordToPackageBuffer(StringBuffer sb, String word, boolean firstWord) {
  		if (JavaUtils.isJavaKeyword(word)) {
  			word = JavaUtils.makeNonJavaKeyword(word);
  		}
  		// separate with dot after the first word
  		if( ! firstWord )
  			sb.append('.');
  
  		// prefix digits with underscores
  		if( Character.isDigit(word.charAt(0)) )
  			sb.append('_');
  
  		// replace periods with underscores
  		if (word.indexOf('.') != -1) {
  			char[] buf = word.toCharArray();
  			for (int i=0; i < word.length(); i++) {
  				if (buf[i] == '.') {
  					buf[i] = '_';
  				}
  			}
  			word = new String(buf);
  		}
  		sb.append( word );
  	}
  
  	/**
  	 * Query Java Local Name
  	 */
  	public static String getJavaLocalName(String fullName) {
  		return fullName.substring(fullName.lastIndexOf('.') + 1);
  	} // getJavaLocalName
  
  	/**
  	 * Query Java Package Name
  	 */
  	public static String getJavaPackageName(String fullName) {
  		if (fullName.lastIndexOf('.') > 0) {
  			return fullName.substring(0, fullName.lastIndexOf('.'));
  		}
  		else {
  			return "";
  		}
  	} // getJavaPackageName
  
  	/**
  	 * Does the given file already exist in the given namespace?
  	 */
  	public static boolean fileExists(String name, String namespace,
  			Namespaces namespaces) throws IOException
  	{
  		String packageName = namespaces.getAsDir(namespace);
  		String fullName = packageName + name;
  		return new File (fullName).exists();
  	} // fileExists
  
  	/**
  	 * A simple map of the primitive types and their holder objects
  	 */
  	private static HashMap TYPES = new HashMap(7);
  
  	static {
  		TYPES.put("int", "java.lang.Integer");
  		TYPES.put("float", "java.lang.Float");
  		TYPES.put("boolean", "java.lang.Boolean");
  		TYPES.put("double", "java.lang.Double");
  		TYPES.put("byte", "java.lang.Byte");
  		TYPES.put("short", "java.lang.Short");
  		TYPES.put("long", "java.lang.Long");
  	}
  
  	/**
  	 * Return a string with "var" wrapped as an Object type if needed
  	 */
  	public static String wrapPrimitiveType(TypeEntry type, String var) {
  		String objType = type == null ? null : (String) TYPES.get(type.getName());
  		if (objType != null) {
  			return "new " + objType + "(" + var + ")";
  		} else if (type != null && 
  				   type.getName().equals("byte[]") &&
  				   type.getQName().getLocalPart().equals("hexBinary")) {
  			// Need to wrap byte[] in special HexBinary object to get the correct serialization
  			return "new org.apache.axis.types.HexBinary(" + var + ")";
  		} else {
  			return var;
  		}
  	} // wrapPrimitiveType
  
  	/**
  	 * Return the Object variable 'var' cast to the appropriate type
  	 * doing the right thing for the primitive types.
  	 */
  	public static String getResponseString(TypeEntry type, MimeInfo mimeInfo,
  			String var) {
  		String mimeType = mimeInfo == null ? null : mimeInfo.getType();
  		String mimeDimensions = mimeInfo == null ? "" : mimeInfo.getDimensions();
  		if (type == null) {
  			return ";";
  		}
  		else if (mimeType != null) {
  			if (mimeType.equals("image/jpeg")) {
  				return "(java.awt.Image" + mimeDimensions + ") " + var + ";";
  			}
  			else if (mimeType.equals("text/plain")) {
  				return "(java.lang.String" + mimeDimensions + ") " + var + ";";
  			}
  			else if (mimeType.equals("text/xml") ||
  					 mimeType.equals("application/xml")) {
  				return "(javax.xml.transform.Source" + mimeDimensions + ") " + var + ";";
  			}
  			else if (mimeType.startsWith("multipart/")) {
  				return "(javax.mail.internet.MimeMultipart" + mimeDimensions + ") " + var + ";";
  			}
  			else if (mimeType.startsWith("application/octetstream")) {
  				return "(org.apache.axis.attachments.OctetStream" + mimeDimensions + ") " + var + ";";
  			}
  			else {
  				return "(" + type.getName() + ") " + var + ";";
  			}
  		}
  		else {
  			String objType = (String) TYPES.get(type.getName());
  			if (objType != null) {
  				return "((" + objType + ") " + var + ")." + type.getName() + "Value();";
  			}
  			else {
  				return "(" + type.getName() + ") " + var + ";";
  			}
  		}
  	} // getResponseString
  
  	public static boolean isPrimitiveType(TypeEntry type) {
  		return TYPES.get(type.getName()) != null;
  	} // isPrimitiveType
  
  	/**
  	 * Return the operation QName.  The namespace is determined from
  	 * the soap:body namespace, if it exists, otherwise it is "".
  	 * 
  	 * @param bindingOper the operation
  	 * @param bEntry the symbol table binding entry
  	 * @param symbolTable SymbolTable  
  	 * @return the operation QName
  	 */ 
  	public static QName getOperationQName(BindingOperation bindingOper, 
  										  BindingEntry bEntry,
  										  SymbolTable symbolTable) {
  
  		Operation operation = bindingOper.getOperation();
  		String operationName = operation.getName();
  
  		// For the wrapped case, use the part element's name...which is
  		// is the same as the operation name, but may have a different
  		// namespace ?
  		// example:
  		//   <part name="paramters" element="ns:myelem">
  		if (bEntry.getBindingStyle() == Style.DOCUMENT &&
  			symbolTable.isWrapped()) {
  			Input input = operation.getInput();
  			if (input != null) {
  				Map parts = input.getMessage().getParts();
  				if (parts != null && !parts.isEmpty()) {
  					Iterator i = parts.values().iterator();
  					Part p = (Part) i.next();
  					return p.getElementName();
  				}
  			}
  		}
  
  		String ns = null;
  
  		// Get a namespace from the soap:body tag, if any
  		// example:
  		//   <soap:body namespace="this_is_what_we_want" ..>
  		BindingInput bindInput = bindingOper.getBindingInput();
  		if (bindInput != null) {
  			Iterator it = bindInput.getExtensibilityElements().iterator();
  			while (it.hasNext()) {
  				ExtensibilityElement elem = (ExtensibilityElement) it.next();
  				if (elem instanceof SOAPBody) {
  					SOAPBody body = (SOAPBody) elem;
  					ns = body.getNamespaceURI();
  					break;
  				} else if (elem instanceof MIMEMultipartRelated) {
  					Object part = null;
  					javax.wsdl.extensions.mime.MIMEMultipartRelated mpr=
  					(javax.wsdl.extensions.mime.MIMEMultipartRelated) elem;
  					List l =  mpr.getMIMEParts();
  					for(int j=0; l!= null && j< l.size() && part == null; j++){
  						javax.wsdl.extensions.mime.MIMEPart mp = (javax.wsdl.extensions.mime.MIMEPart)l.get(j);
  						List ll= mp.getExtensibilityElements();
  						for(int k=0; ll != null && k < ll.size() && part == null; k++){
  							part = ll.get(k);
  							if (part instanceof SOAPBody) {
  								SOAPBody body = (SOAPBody) part;
  								ns = body.getNamespaceURI();
  								break;
  							} else {
  								part = null;
  							}
  					   }
  					}
  				} else if (elem instanceof UnknownExtensibilityElement) {
  					//TODO: After WSDL4J supports soap12, change this code
  					UnknownExtensibilityElement unkElement = (UnknownExtensibilityElement) elem;
  					QName name = unkElement.getElementType();
  					if(name.getNamespaceURI().equals(Constants.URI_WSDL12_SOAP) && 
  					   name.getLocalPart().equals("body")){
  						ns = unkElement.getElement().getAttribute("namespace");
  					}                    
  				}
  			}
  		}
  
  		// If we didn't get a namespace from the soap:body, then
  		// use "".  We should probably use the targetNamespace,
  		// but the target namespace of what?  binding?  portType?
  		// Also, we don't have enough info for to get it.
  		if (ns == null) {
  			ns = "";
  		}
          
  		return new QName(ns, operationName);
  	}
  
  	/**
  	 * Common code for generating a QName in emitted code.  Note that there's
  	 * no semicolon at the end, so we can use this in a variety of contexts.
  	 */ 
  	public static String getNewQName(javax.xml.namespace.QName qname)
  	{
  		return "new javax.xml.namespace.QName(\"" +
  				qname.getNamespaceURI() + "\", \"" +
  				qname.getLocalPart() + "\")";
  	}
  
  	/**
  	 * Get the parameter type name.  If this is a MIME type, then
  	 * figure out the appropriate type from the MIME type, otherwise
  	 * use the name of the type itself.
  	 */
  	public static String getParameterTypeName(Parameter parm) {
  		String ret;
  		if (parm.getMIMEInfo() == null) {
  			ret = parm.getType().getName();
  		}
  		else {
  			String mime = parm.getMIMEInfo().getType();
  			ret = JavaUtils.mimeToJava(mime);
  			if (ret == null) {
  				ret = parm.getType().getName();
  			} else {
  				ret += parm.getMIMEInfo().getDimensions();
  			}
  		}
  		return ret;
  	} // getParameterTypeName
  
  	/** 
  	 * Get the QName that could be used in the xsi:type
  	 * when serializing an object for this parameter/return
  	 * @param param is a parameter
  	 * @return the QName of the parameter's xsi type
  	 */
  	public static QName getXSIType(Parameter param) {
  		if (param.getMIMEInfo() != null) {
  			return getMIMETypeQName(param.getMIMEInfo().getType());
  		}
  		return getXSIType(param.getType());
  	} // getXSIType
  
  	/**
  	 * Get the QName that could be used in the xsi:type
  	 * when serializing an object of the given type.
  	 * @param te is the type entry
  	 * @return the QName of the type's xsi type
  	 */
  	public static QName getXSIType(TypeEntry te) {
  		QName xmlType = null;
  
  		// If the TypeEntry describes an Element, get
  		// the referenced Type.
  		if (te != null &&
  			te instanceof Element &&
  			te.getRefType() != null) {
  			te = te.getRefType();
  		} 
  		// If the TypeEntry is a CollectionTE, use
  		// the TypeEntry representing the component Type
  		// So for example a parameter that takes a 
  		// collection type for
  		// <element name="A" type="xsd:string" maxOccurs="unbounded"/>
  		// will be 
  		// new ParameterDesc(<QName of A>, IN,
  		//                   <QName of xsd:string>,
  		//                   String[])
  		if (te != null &&
  			te instanceof CollectionTE &&
  			te.getRefType() != null) {
  			te = te.getRefType();
  		}
  		if (te != null) {
  			xmlType = te.getQName();
  		}
  		return xmlType;
  	}
  
  	/**
  	 * Given a MIME type, return the AXIS-specific type QName.
  	 * @param mimeName the MIME type name
  	 * @return the AXIS-specific QName for the MIME type
  	 */
  	public static QName getMIMETypeQName(String mimeName) {
  		if ("text/plain".equals(mimeName)) {
  			return Constants.MIME_PLAINTEXT;
  		}
  		else if ("image/gif".equals(mimeName) || "image/jpeg".equals(mimeName)) {
  			return Constants.MIME_IMAGE;
  		}
  		else if ("text/xml".equals(mimeName) || "applications/xml".equals(mimeName)) {
  			return Constants.MIME_SOURCE;
  		}
  		else if ("application/octetstream".equals(mimeName)) {
  			return Constants.MIME_OCTETSTREAM;
  		}
  		else if (mimeName != null && mimeName.startsWith("multipart/")) {
  			return Constants.MIME_MULTIPART;
  		}
  		else {
  			return null;
  		}
  	} // getMIMEType
  
      
  	/**
  	 * Are there any MIME parameters in the given binding?
  	 */
  	public static boolean hasMIME(BindingEntry bEntry) {
  		List operations = bEntry.getBinding().getBindingOperations();
  		for (int i = 0; i < operations.size(); ++i) {
  			BindingOperation operation = (BindingOperation) operations.get(i);
  			if (hasMIME(bEntry, operation)) {
  				return true;
  			}
  		}
  		return false;
  	} // hasMIME
  
  	/**
  	 * Are there any MIME parameters in the given binding's operation?
  	 */
  	public static boolean hasMIME(BindingEntry bEntry, BindingOperation operation) {
  		Parameters parameters =
  		  bEntry.getParameters(operation.getOperation());
  		if (parameters != null) {
  			for (int idx = 0; idx < parameters.list.size(); ++idx) {
  				Parameter p = (Parameter) parameters.list.get(idx);
  				if (p.getMIMEInfo() != null) {
  					return true;
  				}
  			}
  		}
  		return false;
  	} // hasMIME
  
  	private static HashMap constructorMap = new HashMap(50);
  	private static HashMap constructorThrowMap = new HashMap(50);
  	static {
  		//  Type maps to a valid initialization value for that type
  		//      Type var = new Type(arg)
  		// Where "Type" is the key and "new Type(arg)" is the string stored
  		// Used in emitting test cases and server skeletons.
  		constructorMap.put("int", "0");
  		constructorMap.put("float", "0");
  		constructorMap.put("boolean", "true");
  		constructorMap.put("double", "0");
  		constructorMap.put("byte", "(byte)0");
  		constructorMap.put("short", "(short)0");
  		constructorMap.put("long", "0");
  		constructorMap.put("java.lang.Boolean", "new java.lang.Boolean(false)");
  		constructorMap.put("java.lang.Byte", "new java.lang.Byte((byte)0)");
  		constructorMap.put("java.lang.Double", "new java.lang.Double(0)");
  		constructorMap.put("java.lang.Float", "new java.lang.Float(0)");
  		constructorMap.put("java.lang.Integer", "new java.lang.Integer(0)");
  		constructorMap.put("java.lang.Long", "new java.lang.Long(0)");
  		constructorMap.put("java.lang.Short", "new java.lang.Short((short)0)");
  		constructorMap.put("java.math.BigDecimal", "new java.math.BigDecimal(0)");
  		constructorMap.put("java.math.BigInteger", "new java.math.BigInteger(\"0\")");
  		constructorMap.put("java.lang.Object", "new java.lang.String()");
  		constructorMap.put("byte[]", "new byte[0]");
  		constructorMap.put("java.util.Calendar", "java.util.Calendar.getInstance()");
  		constructorMap.put("javax.xml.namespace.QName", "new javax.xml.namespace.QName(\"http://double-double\", \"toil-and-trouble\")");
  		constructorMap.put("org.apache.axis.types.NonNegativeInteger", "new org.apache.axis.types.NonNegativeInteger(\"0\")");
  		constructorMap.put("org.apache.axis.types.PositiveInteger", "new org.apache.axis.types.PositiveInteger(\"1\")");
  		constructorMap.put("org.apache.axis.types.NonPositiveInteger", "new org.apache.axis.types.NonPositiveInteger(\"0\")");
  		constructorMap.put("org.apache.axis.types.NegativeInteger", "new org.apache.axis.types.NegativeInteger(\"-1\")");
  
  		// These constructors throw exception
  		constructorThrowMap.put("org.apache.axis.types.Time", "new org.apache.axis.types.Time(\"15:45:45.275Z\")");
  		constructorThrowMap.put("org.apache.axis.types.UnsignedLong", "new org.apache.axis.types.UnsignedLong(0)");
  		constructorThrowMap.put("org.apache.axis.types.UnsignedInt", "new org.apache.axis.types.UnsignedInt(0)");
  		constructorThrowMap.put("org.apache.axis.types.UnsignedShort", "new org.apache.axis.types.UnsignedShort(0)");
  		constructorThrowMap.put("org.apache.axis.types.UnsignedByte", "new org.apache.axis.types.UnsignedByte(0)");
  		constructorThrowMap.put("org.apache.axis.types.URI", "new org.apache.axis.types.URI(\"urn:testing\")");
  		constructorThrowMap.put("org.apache.axis.types.Year", "new org.apache.axis.types.Year(2000)");
  		constructorThrowMap.put("org.apache.axis.types.Month", "new org.apache.axis.types.Month(1)");
  		constructorThrowMap.put("org.apache.axis.types.Day", "new org.apache.axis.types.Day(1)");
  		constructorThrowMap.put("org.apache.axis.types.YearMonth", "new org.apache.axis.types.YearMonth(2000,1)");
  		constructorThrowMap.put("org.apache.axis.types.MonthDay", "new org.apache.axis.types.MonthDay(1, 1)");
  	}
      
      
  	/**
  	 * Return a constructor for the provided Parameter
  	 * This string will be suitable for assignment:
  	 * <p>
  	 *    Foo var = <i>string returned</i>
  	 * <p>
  	 * Handles basic java types (int, float, etc), wrapper types (Integer, etc)
  	 * and certain java.math (BigDecimal, BigInteger) types.
  	 * Will also handle all Axis specific types (org.apache.axis.types.*)
  	 * <p>
  	 * Caller should expect to wrap the construction in a try/catch block
  	 * if bThrow is set to <i>true</i>.
  	 * 
  	 * @param param info about the parameter we need a constructor for
  	 * @param symbolTable used to lookup enumerations
  	 * @param bThrow set to true if contructor needs try/catch block
  	 */ 
  	public static String getConstructorForParam(Parameter param, 
  										 SymbolTable symbolTable,
  										 BooleanHolder bThrow) {
          
  		String paramType = param.getType().getName();
  		String mimeType = param.getMIMEInfo() == null ? null : param.getMIMEInfo().getType();
  		String mimeDimensions = param.getMIMEInfo() == null ? "" : param.getMIMEInfo().getDimensions();
  		String out = null;
          
  		// Handle mime types
  		if (mimeType != null) {
  			if (mimeType.equals("image/gif") ||
  					mimeType.equals("image/jpeg")) {
  				return "null";
  			}
  			else if (mimeType.equals("text/xml") ||
  					mimeType.equals("application/xml")) {
  				if(mimeDimensions.length() <= 0)
  					return "new javax.xml.transform.stream.StreamSource()";
  				else
  					return "new javax.xml.transform.stream.StreamSource[0]";
  			}
  			else if (mimeType.equals("application/octetstream")) {
  				if(mimeDimensions.length() <= 0)
  					return "new org.apache.axis.attachments.OctetStream()";
  				else
  					return "new org.apache.axis.attachments.OctetStream[0]";
  			}
  			else {
  				return "new " + Utils.getParameterTypeName(param) + "()";
  			}
  		}
          
  		// Look up paramType in the table
  		out = (String) constructorMap.get(paramType);
  		if (out != null) {
  			return out;
  		}
          
  		// Look up paramType in the table of constructors that can throw exceptions
  		out = (String) constructorThrowMap.get(paramType);
  		if (out != null) {
  			bThrow.value = true;
  			return out;
  		}
          
  		// Handle arrays
  		if (paramType.endsWith("[]")) {
  			return "new " + JavaUtils.replace(paramType, "[]", "[0]");
  		}
  
  		/*** We have some constructed type. */
          
  		// Check for enumeration
  		Vector v = Utils.getEnumerationBaseAndValues(
  				param.getType().getNode(), symbolTable);
  		if (v != null) {
  			// This constructed type is an enumeration.  Use the first one.
  			String enumeration = (String)
  					JavaEnumTypeWriter.getEnumValueIds(v).get(0);
  			return paramType + "." + enumeration;
  		}
          
  		// This constructed type is a normal type, instantiate it.
  		return "new " + paramType + "()";
          
  	}
  
  } // class Utils