TypeEntry.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.jboss.axis.wsdl.symbolTable; import org.jboss.axis.utils.Messages; import org.w3c.dom.Node; import javax.xml.namespace.QName; import java.io.IOException; /** * This class represents a wsdl types entry that is supported by the WSDL2Java emitter. * A TypeEntry has a QName representing its XML name and a name, which in the * WSDL2Java back end is its full java name. The TypeEntry may also have a Node, * which locates the definition of the emit type in the xml. * A TypeEntry object extends SymTabEntry and is built by the SymbolTable class for * each supported root complexType, simpleType, and elements that are * defined or encountered. * <p/> * SymTabEntry * | * TypeEntry * / \ * Type Element * | | * (BaseType, (DefinedElement, * CollectionType CollectionElement, * DefinedType, UndefinedElement) * UndefinedType) * <p/> * UndefinedType and UndefinedElement are placeholders when the real type or element * is not encountered yet. Both of these implement the Undefined interface. * <p/> * A TypeEntry whose java (or other language) name depends on an Undefined type, will * have its name initialization deferred until the Undefined type is replaced with * a defined type. The updateUndefined() method is invoked by the UndefinedDelegate to * update the information. * <p/> * Each TypeEntry whose language name depends on another TypeEntry will have the refType * field set. For example: * <element name="foo" type="bar" /> * The TypeEntry for "foo" will have a refType set to the TypeEntry of "bar". * <p/> * Another Example: * <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> * The TypeEntry for "hobbyArray" will have a refType that locates the TypeEntry for xsd:string * and the dims field will be "[]" * * @author Rich Scheuerle (scheu@us.ibm.com) */ public abstract class TypeEntry extends SymTabEntry { protected Node node; // Node protected TypeEntry refType; // Some TypeEntries refer to other types. protected String dims = ""; // If refType is an element, dims indicates // the array dims (for example "[]"). protected boolean undefined; // If refType is an Undefined type // (or has a refType that is Undefined) // then the undefined flag is set. // The name cannot be determined // until the Undefined type is found. protected boolean isBaseType;// Indicates if represented by a // primitive or util class protected boolean isSimpleType = false; // Indicates if this type is a simple type protected boolean onlyLiteralReference = false; // Indicates // whether this type is only referenced // via a binding's literal use. /** * Create a TypeEntry object for an xml construct that references another type. * Defer processing until refType is known. */ protected TypeEntry(QName pqName, TypeEntry refType, Node pNode, String dims) { super(pqName); node = pNode; this.undefined = refType.undefined; this.refType = refType; if (dims == null) dims = ""; this.dims = dims; if (refType.undefined) { // Need to defer processing until known. TypeEntry uType = refType; while (!(uType instanceof Undefined)) { uType = uType.refType; } ((Undefined)uType).register(this); } else { isBaseType = (refType.isBaseType && refType.dims.equals("") && dims.equals("")); } //System.out.println(toString()); } /** * Create a TypeEntry object for an xml construct that is not a base type */ protected TypeEntry(QName pqName, Node pNode) { super(pqName); node = pNode; refType = null; undefined = false; dims = ""; isBaseType = false; //System.out.println(toString()); } /** * Create a TypeEntry object for an xml construct name that represents a base type */ protected TypeEntry(QName pqName) { super(pqName); node = null; undefined = false; dims = ""; isBaseType = true; //System.out.println(toString()); } /** * Query the node for this type. */ public Node getNode() { return node; } /** * Returns the Base Type Name. * For example if the Type represents a schema integer, "int" is returned. * If this is a user defined type, null is returned. */ public String getBaseType() { if (isBaseType) { return name; } else { return null; } } public boolean isBaseType() { return isBaseType; } public boolean isSimpleType() { return isSimpleType; } public void setSimpleType(boolean simpleType) { isSimpleType = simpleType; } /** * Is this type references ONLY as a literal type? If a binding's * message's soapBody says: use="literal", then a type is referenced * literally. Note that that type's contained types (ie., an address * contains a phone#) are not referenced literally. Since a type * that is ONLY referenced as a literal may cause a generator to act * differently (like WSDL2Java), this extra reference distinction is * needed. */ public boolean isOnlyLiteralReferenced() { return onlyLiteralReference; } // isOnlyLiteralReferenced /** * Set the isOnlyLiteralReference flag. */ public void setOnlyLiteralReference(boolean set) { onlyLiteralReference = set; } // setOnlyLiteralRefeerence /** * getUndefinedTypeRef returns the Undefined TypeEntry that this entry depends on or NULL. */ protected TypeEntry getUndefinedTypeRef() { if (this instanceof Undefined) return this; if (undefined && refType != null) { if (refType.undefined) { TypeEntry uType = refType; while (!(uType instanceof Undefined)) { uType = uType.refType; } return uType; } } return null; } /** * UpdateUndefined is called when the ref TypeEntry is finally known. * * @param oldRef The TypeEntry representing the Undefined TypeEntry * @param newRef The replacement TypeEntry * @return true if TypeEntry is changed in any way. */ protected boolean updateUndefined(TypeEntry oldRef, TypeEntry newRef) throws IOException { boolean changedState = false; // Replace refType with the new one if applicable if (refType == oldRef) { refType = newRef; changedState = true; // Detect a loop TypeEntry te = refType; while (te != null && te != this) { te = te.refType; } if (te == this) { // Detected a loop. undefined = false; isBaseType = false; node = null; throw new IOException(Messages.getMessage("undefinedloop00", getQName().toString())); } } // Update information if refType is now defined if (refType != null && undefined && refType.undefined == false) { undefined = false; changedState = true; isBaseType = (refType.isBaseType && refType.dims.equals("") && dims.equals("")); } return changedState; } /** * If this type references another type, return that type, otherwise return null. */ public TypeEntry getRefType() { return refType; } // getRefType public void setRefType(TypeEntry refType) { this.refType = refType; } /** * Return the dimensions of this type, which can be 0 or more "[]". */ public String getDimensions() { return dims; } // getDimensions /** * Get string representation. */ public String toString() { return toString(""); } /** * Get string representation with indentation */ protected String toString(String indent) { String refString = indent + "RefType: null \n"; if (refType != null) refString = indent + "RefType:\n" + refType.toString(indent + " ") + "\n"; return super.toString(indent) + indent + "Class: " + this.getClass().getName() + "\n" + indent + "Base?: " + isBaseType + "\n" + indent + "Undefined?: " + undefined + "\n" + indent + "isSimpleType? " + isSimpleType + "\n" + indent + "Node: " + getNode() + "\n" + indent + "Dims: " + dims + "\n" + refString; } } ;
TypeEntry.java |