Package org.apache.axis.wsdl.toJava

Source Code of org.apache.axis.wsdl.toJava.JavaBeanWriter

/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2001 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 java.io.IOException;
import java.io.PrintWriter;

import java.util.Vector;

import org.apache.axis.utils.JavaUtils;

import org.apache.axis.wsdl.symbolTable.ElementDecl;
import org.apache.axis.wsdl.symbolTable.SchemaUtils;
import org.apache.axis.wsdl.symbolTable.TypeEntry;
import org.apache.axis.Constants;

import org.w3c.dom.Node;

import javax.xml.namespace.QName;

/**
* This is Wsdl2java's Complex Type Writer.  It writes the <typeName>.java file.
*/
public class JavaBeanWriter extends JavaClassWriter {
    private TypeEntry type;
    private Vector elements;
    private Vector attributes;
    private TypeEntry extendType;
    protected JavaBeanHelperWriter helper;
    protected Vector names = new Vector(); // even indices: types, odd: vars
    protected String simpleValueType = null// name of type of simple value
    protected PrintWriter pw;

    // The following fields can be set by extended classes
    // to control processing
    protected boolean enableDefaultConstructor = true;
    protected boolean enableFullConstructor = false;
    protected boolean enableSimpleConstructors = false;
    protected boolean enableToString = false;
    protected boolean enableSetters = true;
    protected boolean enableGetters = true;
    protected boolean enableEquals = true;
    protected boolean enableHashCode = true;

    /**
     * Constructor.
     * @param emitter
     * @param type        The type representing this class
     * @param elements    Vector containing the Type and name of each property
     * @param extendType  The type representing the extended class (or null)
     * @param attributes  Vector containing the attribute types and names
     * @param helper      Helper class writer
     */
    protected JavaBeanWriter(
            Emitter emitter,
            TypeEntry type,
            Vector elements,
            TypeEntry extendType,
            Vector attributes,
            JavaWriter helper) {
        super(emitter, type.getName(), "complexType");
        this.type = type;
        this.elements = elements;
        this.attributes = attributes;
        this.extendType = extendType;
        this.helper = (JavaBeanHelperWriter) helper;
        if (type.isSimpleType()) {
            enableSimpleConstructors = true;
            enableToString = true;
        }
    } // ctor

    /**
     * Generate the binding for the given complex type.
     */
    protected void writeFileBody(PrintWriter pw) throws IOException {

        this.pw = pw;

        // Populate Names Vector with the names and types of the members.
        // The write methods use the names vector whenever they need to get
        // a member name or type.
        preprocess();

        // Write Member Fields
        writeMemberFields();

        // Write the default constructor
        if (enableDefaultConstructor) {
            writeDefaultConstructor();
        }

        // Write Full Constructor
        if (enableFullConstructor) {
            writeFullConstructor();
        }

        // Write SimpleConstructors
        if (enableSimpleConstructors) {
            writeSimpleConstructors();
        }

        // Write ToString method
        if (enableToString) {
            writeToStringMethod();
        }

        // Write accessor methods
        writeAccessMethods();

        // Write general purpose equals and hashCode methods
        if (enableEquals) {
            writeEqualsMethod();
        }
        if (enableHashCode) {
            writeHashCodeMethod();
        }

        // Write the meta data into a Helper class or
        // embed it in the bean class
        if (!emitter.isHelperWanted()) {
            // Write the helper info into the bean class
            helper.setPrintWriter(pw);
        }
        helper.generate();
    } // writeFileBody

    /**
     * Builds the names String vector.
     * The even indices are the java class names of the
     * member fields.  The odd indices are the member variable
     * names.
     * Also sets the simpleValueType variable to the
     * java class name of the simple value if this bean represents
     * a simple type
     */
    protected void preprocess() {
        // Add element names
        if (elements != null) {
            for (int i = 0; i < elements.size(); i++) {
                ElementDecl elem = (ElementDecl)elements.get(i);
                String typeName = elem.getType().getName();
                String variableName;
                if (elem.getAnyElement()) {
                    typeName = "org.apache.axis.message.MessageElement []";
                    variableName = Constants.ANYCONTENT;
                } else {
                    String elemName = elem.getName().getLocalPart();
                    variableName = Utils.xmlNameToJava(elemName);
                }
                names.add(typeName);
                names.add(variableName);
                if (type.isSimpleType() &&
                    variableName.equals("value")) {
                    simpleValueType = typeName;
                }
            }
        }
        // Add attribute names
        if (attributes != null) {
            for (int i = 0; i < attributes.size(); i += 2) {
                String typeName = ((TypeEntry) attributes.get(i)).getName();
                QName xmlName = (QName) attributes.get(i + 1);
                String variableName =
                    Utils.xmlNameToJava(xmlName.getLocalPart());
                names.add(typeName);
                names.add(variableName);
                if (type.isSimpleType() &&
                    variableName.equals("value")) {
                    simpleValueType = typeName;
                }
            }
        }
    }

    /**
     * Returns the appropriate extends text
     * @return "" or "abstract "
     */
    protected String getClassModifiers() {
        Node node = type.getNode();
        if (node != null) {
            if (JavaUtils.isTrueExplicitly(Utils.getAttribute(node, "abstract"))) {
                return super.getClassModifiers() + "abstract ";
            }
        }
        return super.getClassModifiers();
    } // getClassModifiers

    /**
     * Returns the appropriate extends text
     * @return "" or " extends <class> "
     */
    protected String getExtendsText() {
        // See if this class extends another class
        String extendsText = "";
        if (extendType != null && !type.isSimpleType()) {
            extendsText = " extends " + extendType.getName() + " ";
        }
        return extendsText;
    }

    /**
     * Returns the appropriate implements text
     * @return " implements <classes> "
     */
    protected String getImplementsText() {
        // See if this class extends another class
        String implementsText = " implements java.io.Serializable";
        if (type.isSimpleType()) {
            implementsText += ", org.apache.axis.encoding.SimpleType";
        }
        implementsText += " ";
        return implementsText;
    }

    /**
     * Writes the member fields.
     */
    protected void writeMemberFields() {
        // Define the member element of the bean
        for (int i = 0; i < names.size(); i += 2) {
            String typeName = (String) names.get(i);
            String variable = (String) names.get(i + 1);

            // Declare the bean element
            pw.print("    private " + typeName + " " + variable + ";");

            // label the attribute fields.
            if (elements == null || i >= (elements.size()*2))
                pw.println("  // attribute");
            else
                pw.println();
        }
        pw.println();
    }

    /**
     * Writes the default constructor.
     */
    protected void writeDefaultConstructor() {
        // Define the default constructor
        pw.println("    public " + className + "() {");
        pw.println("    }");
        pw.println();
    }

    /**
     * Writes the full constructor.
     * Note that this class is not recommended for
     * JSR 101 compliant beans, but is provided for
     * extended classes which may wish to generate a full
     * constructor.
     */
    protected void writeFullConstructor() {
        // The constructor needs to consider all extended types
        Vector extendList = new Vector();
        extendList.add(type);
        TypeEntry parent = extendType;
        while(parent != null) {
            extendList.add(parent);
            parent = SchemaUtils.getComplexElementExtensionBase(
                parent.getNode(),
                emitter.getSymbolTable());
        }

        // Now generate a list of names and types starting with
        // the oldest parent.  (Attrs are considered before elements).
        Vector paramTypes = new Vector();
        Vector paramNames = new Vector();
        for (int i=extendList.size()-1; i >= 0; i--) {
            TypeEntry te = (TypeEntry) extendList.elementAt(i);

            // The names of the inherited parms are mangled
            // in case they interfere with local parms.
            String mangle = "";
            if (i > 0) {
                mangle = "_" +
                    Utils.xmlNameToJava(te.getQName().getLocalPart()) +
                    "_";
            }
            // Process the attributes
            Vector attributes = SchemaUtils.getContainedAttributeTypes(
                te.getNode(), emitter.getSymbolTable());
            if (attributes != null) {
                for (int j=0; j<attributes.size(); j+=2) {
                    paramTypes.add(((TypeEntry) attributes.get(j)).getName());
                    String name = ((QName)attributes.get(j + 1)).getLocalPart();
                    paramNames.add(mangle + Utils.xmlNameToJava(name));
                }
            }
            // Process the elements
            Vector elements = SchemaUtils.getContainedElementDeclarations(
                te.getNode(), emitter.getSymbolTable());
            if (elements != null) {
                for (int j=0; j<elements.size(); j++) {
                    ElementDecl elem = (ElementDecl)elements.get(j);
                    paramTypes.add(elem.getType().getName());
                    paramNames.add(mangle +
                        Utils.xmlNameToJava(elem.getName().getLocalPart()));
                }
            }
        }
        // Set the index where the local params start
        int localParams = paramTypes.size() - names.size()/2;


        // Now write the constructor signature
        if (paramTypes.size() > 0) {
            pw.println("    public " + className + "(");
            for (int i=0; i<paramTypes.size(); i++) {
                pw.print("           " + paramTypes.elementAt(i) +
                         " " + paramNames.elementAt(i));
                if ((i+1) < paramTypes.size()) {
                    pw.println(",");
                } else {
                    pw.println(") {");
                }
            }

            // Call the extended constructor to set inherited fields
            if (extendType != null) {
                pw.println("        super(");
                for (int j=0; j<localParams; j++) {
                    pw.print("            " + paramNames.elementAt(j));
                    if ((j+1) < localParams) {
                        pw.println(",");
                    } else {
                        pw.println(");");
                    }
                }
            }
            // Set local fields directly
            for (int j=localParams; j<paramNames.size(); j++) {
                pw.println("        this." + paramNames.elementAt(j) +
                           " = " + paramNames.elementAt(j)+ ";");
            }
            pw.println("    }");
            pw.println();
        }
    }

    /**
     * Writes the constructors for SimpleTypes.
     * Writes a constructor accepting a string and
     * a constructor accepting the simple java type.
     */
    protected void writeSimpleConstructors() {
        // If this is a simple type,need to emit a string
        // constructor and a value construtor.
        if (type.isSimpleType() && simpleValueType != null) {
            if (!simpleValueType.equals("java.lang.String")) {
                pw.println("    public " + className + "(" +
                           simpleValueType + " value) {");
                pw.println("        this.value = value;");
                pw.println("    }");
                pw.println();
            }

            pw.println("    // " + JavaUtils.getMessage("needStringCtor"));
            pw.println("    public " + className + "(java.lang.String value) {");
            // Make sure we wrap base types with its Object type
            String wrapper = JavaUtils.getWrapper(simpleValueType);

            if (wrapper != null) {
                pw.println("        this.value = new " + wrapper +
                           "(value)." + simpleValueType + "Value();");
            } else {
                if (simpleValueType.equals("byte[]")) {
                    pw.println("        this.value = value.getBytes();");
                }
                else if (simpleValueType.equals("org.apache.axis.types.URI")) {
                    pw.println("        try {");
                    pw.println("            this.value = new org.apache.axis.types.URI(value);");
                    pw.println("        }");
                    pw.println("        catch (org.apache.axis.types.URI.MalformedURIException mue) {");
                    pw.println("            this.value = new org.apache.axis.types.URI();");
                    pw.println("       }");
                }
                else {
                    pw.println("        this.value = new " +
                               simpleValueType + "(value);");
                }
            }
            pw.println("    }");
            pw.println();
        }
    }

    /**
     * Writes the toString method
     * Currently the toString method is only written for
     * simpleTypes.
     */
    protected void writeToStringMethod() {
        // If this is a simple type, emit a toString
        if (type.isSimpleType() && simpleValueType != null) {
            pw.println("    // " + JavaUtils.getMessage("needToString"));
            String wrapper = JavaUtils.getWrapper(simpleValueType);
            pw.println("    public java.lang.String toString() {");
            if (wrapper != null) {
                pw.println("        return new " + wrapper + "(value).toString();");
            } else {
                pw.println("        return value == null ? null : value.toString();");
            }
            pw.println("    }");
            pw.println();
        }
    }

    /**
     * Writes the setter and getter methods
     */
    protected void writeAccessMethods() {
        int j = 0;
        // Define getters and setters for the bean elements
        for (int i = 0; i < names.size(); i += 2, j++) {
            String typeName = (String) names.get(i);
            String name = (String) names.get(i + 1);
            String capName = Utils.capitalizeFirstChar(name);

            String get = "get";
            if (typeName.equals("boolean"))
                get = "is";

            if (enableGetters) {
                pw.println("    public " + typeName + " " +
                           get + capName + "() {");
                pw.println("        return " + name + ";");
                pw.println("    }");
                pw.println();
            }
            if (enableSetters) {
                pw.println("    public void set" + capName + "(" +
                           typeName + " " + name + ") {");
                pw.println("        this." + name + " = " + name + ";");
                pw.println("    }");
                pw.println();
            }

            // If this is a special collection type, insert extra
            // java code so that the serializer/deserializer can recognize
            // the class.  This is not JAX-RPC, and will be replaced with
            // compliant code when JAX-RPC determines how to deal with this case.
            // These signatures comply with Bean Indexed Properties which seems
            // like the reasonable approach to take for collection types.
            // (It may be more efficient to handle this with an ArrayList...but
            // for the initial support it was easier to use an actual array.)
            if (elements != null && j < elements.size()) {
                ElementDecl elem = (ElementDecl)elements.get(j);
                if (elem.getType().getQName().getLocalPart().indexOf("[") > 0) {
                    String compName = typeName.substring(0, typeName.lastIndexOf("["));
                    if (enableGetters) {
                        pw.println("    public " + compName + " " + get + capName +
                                   "(int i) {");
                        pw.println("        return " + name + "[i];");
                        pw.println("    }");
                        pw.println();
                    }
                    if (enableSetters) {
                        pw.println("    public void set" + capName + "(int i, " +
                                   compName + " value) {");
                        // According to the section 7.2 of the JavaBeans
                        // specification, the indexed setter should not
                        // establish or grow the array.  Thus the following
                        // code is not generated for compliance purposes.
                        /*
                        int bracketIndex = typeName.indexOf("[");
                        String newingName = typeName.substring(0, bracketIndex + 1);
                        String newingSuffix = typeName.substring(bracketIndex + 1);

                        pw.println("        if (this." + name + " == null ||");
                        pw.println("            this." + name + ".length <= i) {");
                        pw.println("            " + typeName + " a = new " +
                                   newingName + "i + 1" + newingSuffix + ";");
                        pw.println("            if (this." + name + " != null) {");
                        pw.println("                for(int j = 0; j < this." + name +
                                   ".length; j++)");
                        pw.println("                    a[j] = this." + name + "[j];");
                        pw.println("            }");
                        pw.println("            this." + name + " = a;");
                        pw.println("        }");
                        */
                        pw.println("        this." + name + "[i] = value;");
                        pw.println("    }");
                        pw.println();
                    }
                }
            }
        }
    }

    /**
     * Writes a general purpose equals method
     */
    protected void writeEqualsMethod() {

        // The __equalsCalc field and synchronized method are necessary
        // in case the object has direct or indirect references to itself.
        pw.println("    private java.lang.Object __equalsCalc = null;");
        pw.println("    public synchronized boolean equals(java.lang.Object obj) {");

        // First do the general comparison checks
        pw.println("        if (!(obj instanceof " + className + ")) return false;");
        pw.println("        " +  className + " other = (" + className + ") obj;");
        pw.println("        if (obj == null) return false;");
        pw.println("        if (this == obj) return true;");

        // Have we been here before ? return true if yes otherwise false
        pw.println("        if (__equalsCalc != null) {");
        pw.println("            return (__equalsCalc == obj);");
        pw.println("        }");
        pw.println("        __equalsCalc = obj;");

        // Before checking the elements, check equality of the super class
        String truth = "true";
        if (extendType != null && !type.isSimpleType()) {
            truth = "super.equals(obj)";
        }
        pw.println("        boolean _equals;");
        if (names.size() == 0) {
            pw.println("        _equals = " + truth + ";");
        } else {
            pw.println("        _equals = " + truth + " && ");
            for (int i = 0; i < names.size(); i += 2) {
                String variableType = (String) names.get(i);
                String variable = (String) names.get(i + 1);
                String get = "get";

                if (variableType.equals("boolean"))
                    get = "is";

                if (variableType.equals("int") ||
                        variableType.equals("long") ||
                        variableType.equals("short") ||
                        variableType.equals("float") ||
                        variableType.equals("double") ||
                        variableType.equals("boolean") ||
                        variableType.equals("byte")) {
                    pw.print("            " + variable + " == other." + get +
                            Utils.capitalizeFirstChar(variable) + "()");
                } else if (variableType.indexOf("[") >=0) {
                    // Use java.util.Arrays.equals to compare arrays.
                    pw.println("            ((" + variable +
                               "==null && other." + get +
                               Utils.capitalizeFirstChar(variable) + "()==null) || ");
                    pw.println("             (" + variable + "!=null &&");
                    pw.print("              java.util.Arrays.equals(" + variable +
                             ", other." + get +
                             Utils.capitalizeFirstChar(variable) + "())))");

                } else {
                    pw.println("            ((" + variable +
                               "==null && other." + get +
                               Utils.capitalizeFirstChar(variable) + "()==null) || ");
                    pw.println("             (" + variable + "!=null &&");
                    pw.print("              " + variable +
                             ".equals(other." + get +
                             Utils.capitalizeFirstChar(variable) + "())))");
                }
                if (i == (names.size() - 2))
                    pw.println(";");
                else
                    pw.println(" &&");
            }
        }
        pw.println("        __equalsCalc = null;");
        pw.println("        return _equals;");
        pw.println("    }");
        pw.println("");
    }

    /**
     * Writes a general purpose hashCode method.
     */
    protected void writeHashCodeMethod() {
        // The __hashCodeCalc field and synchronized method are necessary
        // in case the object has direct or indirect references to itself.
        pw.println("    private boolean __hashCodeCalc = false;");
        pw.println("    public synchronized int hashCode() {");
        pw.println("        if (__hashCodeCalc) {");
        pw.println("            return 0;");
        pw.println("        }");
        pw.println("        __hashCodeCalc = true;");

        // Get the hashCode of the super class
        String start = "1";
        if (extendType != null && !type.isSimpleType()) {
            start = "super.hashCode()";
        }
        pw.println("        int _hashCode = " + start + ";");
        for (int i = 0; i < names.size(); i += 2) {
            String variableType = (String) names.get(i);
            String variable = (String) names.get(i + 1);
            String get = "get";

            if (variableType.equals("boolean"))
                get = "is";

            if (variableType.equals("int") ||
                variableType.equals("short") ||
                variableType.equals("byte")) {
                pw.println("        _hashCode += " + get +
                         Utils.capitalizeFirstChar(variable) + "();");
            } else if (variableType.equals("boolean")) {
                pw.println("        _hashCode += new Boolean(" + get +
                           Utils.capitalizeFirstChar(variable) + "()).hashCode();");
            } else if (variableType.equals("long")) {
                pw.println("        _hashCode += new Long(" + get +
                           Utils.capitalizeFirstChar(variable) + "()).hashCode();");
            } else if (variableType.equals("float")) {
                pw.println("        _hashCode += new Float(" + get +
                           Utils.capitalizeFirstChar(variable) + "()).hashCode();");
            } else if (variableType.equals("double")) {
                pw.println("        _hashCode += new Double(" + get +
                           Utils.capitalizeFirstChar(variable) + "()).hashCode();");
            } else if (variableType.indexOf("[") >=0) {
                // The hashCode calculation for arrays is complicated.
                // Wish there was a hashCode method in java.utils.Arrays !
                // Get the hashCode for each element of the array which is not an array.
                pw.println("        if (" + get +
                           Utils.capitalizeFirstChar(variable) + "() != null) {");
                pw.println("            for (int i=0;");
                pw.println("                 i<java.lang.reflect.Array.getLength(" + get +
                           Utils.capitalizeFirstChar(variable) + "());");
                pw.println("                 i++) {");
                pw.println("                java.lang.Object obj = java.lang.reflect.Array.get(" +
                           get +
                           Utils.capitalizeFirstChar(variable) + "(), i);");
                pw.println("                if (obj != null &&");
                pw.println("                    !obj.getClass().isArray()) {");
                pw.println("                    _hashCode += obj.hashCode();");
                pw.println("                }");
                pw.println("            }");
                pw.println("        }");
            } else {
                pw.println("        if (" + get +
                           Utils.capitalizeFirstChar(variable) + "() != null) {");
                pw.println("            _hashCode += " + get +
                           Utils.capitalizeFirstChar(variable) + "().hashCode();");
                pw.println("        }");
            }
        }
        // Reset the __hashCodeCalc variable and return
        pw.println("        __hashCodeCalc = false;");
        pw.println("        return _hashCode;");
        pw.println("    }");
        pw.println("");
    }
} // class JavaBeanWriter
TOP

Related Classes of org.apache.axis.wsdl.toJava.JavaBeanWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.