KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > wsdl > toJava > JavaBeanWriter


1 /*
2 * The Apache Software License, Version 1.1
3 *
4 *
5 * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
6 * reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution,
21 * if any, must include the following acknowledgment:
22 * "This product includes software developed by the
23 * Apache Software Foundation (http://www.apache.org/)."
24 * Alternately, this acknowledgment may appear in the software itself,
25 * if and wherever such third-party acknowledgments normally appear.
26 *
27 * 4. The names "Axis" and "Apache Software Foundation" must
28 * not be used to endorse or promote products derived from this
29 * software without prior written permission. For written
30 * permission, please contact apache@apache.org.
31 *
32 * 5. Products derived from this software may not be called "Apache",
33 * nor may "Apache" appear in their name, without prior written
34 * permission of the Apache Software Foundation.
35 *
36 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 * SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This software consists of voluntary contributions made by many
51 * individuals on behalf of the Apache Software Foundation. For more
52 * information on the Apache Software Foundation, please see
53 * <http://www.apache.org/>.
54 */

55 package org.jboss.axis.wsdl.toJava;
56
57 import org.jboss.axis.Constants;
58 import org.jboss.axis.message.SOAPElementAxisImpl;
59 import org.jboss.axis.utils.JavaUtils;
60 import org.jboss.axis.utils.Messages;
61 import org.jboss.axis.wsdl.symbolTable.ElementDecl;
62 import org.jboss.axis.wsdl.symbolTable.SchemaUtils;
63 import org.jboss.axis.wsdl.symbolTable.TypeEntry;
64 import org.w3c.dom.Node JavaDoc;
65
66 import javax.xml.namespace.QName JavaDoc;
67 import java.io.IOException JavaDoc;
68 import java.io.PrintWriter JavaDoc;
69 import java.util.Vector JavaDoc;
70
71 /**
72  * This is Wsdl2java's Complex Type Writer. It writes the <typeName>.java file.
73  */

74 public class JavaBeanWriter extends JavaClassWriter
75 {
76    private TypeEntry type;
77    private Vector JavaDoc elements;
78    private Vector JavaDoc attributes;
79    private TypeEntry extendType;
80    protected JavaBeanHelperWriter helper;
81    protected Vector JavaDoc names = new Vector JavaDoc(); // even indices: types, odd: vars
82
protected String JavaDoc simpleValueType = null; // name of type of simple value
83
protected PrintWriter JavaDoc pw;
84
85    // The following fields can be set by extended classes
86
// to control processing
87
protected boolean enableDefaultConstructor = true;
88    protected boolean enableFullConstructor = false;
89    protected boolean enableSimpleConstructors = false;
90    protected boolean enableToString = false;
91    protected boolean enableSetters = true;
92    protected boolean enableGetters = true;
93    protected boolean enableEquals = true;
94    protected boolean enableHashCode = true;
95
96    /**
97     * Constructor.
98     *
99     * @param emitter
100     * @param type The type representing this class
101     * @param elements Vector containing the Type and name of each property
102     * @param extendType The type representing the extended class (or null)
103     * @param attributes Vector containing the attribute types and names
104     * @param helper Helper class writer
105     */

106    protected JavaBeanWriter(Emitter emitter,
107                             TypeEntry type,
108                             Vector JavaDoc elements,
109                             TypeEntry extendType,
110                             Vector JavaDoc attributes,
111                             JavaWriter helper)
112    {
113       super(emitter, type.getName(), "complexType");
114       this.type = type;
115       this.elements = elements;
116       this.attributes = attributes;
117       this.extendType = extendType;
118       this.helper = (JavaBeanHelperWriter)helper;
119       if (type.isSimpleType())
120       {
121          enableSimpleConstructors = true;
122          enableToString = true;
123       }
124    } // ctor
125

126    /**
127     * Generate the binding for the given complex type.
128     */

129    protected void writeFileBody(PrintWriter JavaDoc pw) throws IOException JavaDoc
130    {
131
132       this.pw = pw;
133
134       // Populate Names Vector with the names and types of the members.
135
// The write methods use the names vector whenever they need to get
136
// a member name or type.
137
preprocess();
138
139       // Write Member Fields
140
writeMemberFields();
141
142       // Write the default constructor
143
if (enableDefaultConstructor)
144       {
145          writeDefaultConstructor();
146       }
147
148       // Write Full Constructor
149
if (enableFullConstructor)
150       {
151          writeFullConstructor();
152       }
153
154       // Write SimpleConstructors
155
if (enableSimpleConstructors)
156       {
157          writeSimpleConstructors();
158       }
159
160       // Write ToString method
161
if (enableToString)
162       {
163          writeToStringMethod();
164       }
165
166       // Write accessor methods
167
writeAccessMethods();
168
169       // Write general purpose equals and hashCode methods
170
if (enableEquals)
171       {
172          writeEqualsMethod();
173       }
174       if (enableHashCode)
175       {
176          writeHashCodeMethod();
177       }
178
179       // Write the meta data into a Helper class or
180
// embed it in the bean class
181
if (!emitter.isHelperWanted())
182       {
183          // Write the helper info into the bean class
184
helper.setPrintWriter(pw);
185       }
186       helper.generate();
187    } // writeFileBody
188

189    /**
190     * Builds the names String vector.
191     * The even indices are the java class names of the
192     * member fields. The odd indices are the member variable
193     * names.
194     * Also sets the simpleValueType variable to the
195     * java class name of the simple value if this bean represents
196     * a simple type
197     */

198    protected void preprocess()
199    {
200       // Add element names
201
if (elements != null)
202       {
203          for (int i = 0; i < elements.size(); i++)
204          {
205             ElementDecl elem = (ElementDecl)elements.get(i);
206             String JavaDoc typeName = elem.getType().getName();
207             String JavaDoc variableName;
208             if (elem.getAnyElement())
209             {
210                typeName = SOAPElementAxisImpl.class.getName() + "[]";
211                variableName = Constants.ANYCONTENT;
212             }
213             else
214             {
215                String JavaDoc elemName = elem.getName().getLocalPart();
216                variableName = Utils.xmlNameToJava(elemName);
217             }
218             names.add(typeName);
219             names.add(variableName);
220             if (type.isSimpleType() &&
221                     variableName.equals("value"))
222             {
223                simpleValueType = typeName;
224             }
225          }
226       }
227       // Add attribute names
228
if (attributes != null)
229       {
230          for (int i = 0; i < attributes.size(); i += 2)
231          {
232             String JavaDoc typeName = ((TypeEntry)attributes.get(i)).getName();
233             QName JavaDoc xmlName = (QName JavaDoc)attributes.get(i + 1);
234             String JavaDoc variableName =
235                     Utils.xmlNameToJava(xmlName.getLocalPart());
236             names.add(typeName);
237             names.add(variableName);
238             if (type.isSimpleType() &&
239                     variableName.equals("value"))
240             {
241                simpleValueType = typeName;
242             }
243          }
244       }
245
246       if (extendType != null && extendType.getDimensions().equals("[]"))
247       {
248          String JavaDoc typeName = extendType.getName();
249          String JavaDoc elemName = extendType.getQName().getLocalPart();
250          String JavaDoc variableName = Utils.xmlNameToJava(elemName);
251          names.add(typeName);
252          names.add(variableName);
253       }
254    }
255
256    /**
257     * Returns the appropriate extends text
258     *
259     * @return "" or "abstract "
260     */

261    protected String JavaDoc getClassModifiers()
262    {
263       Node JavaDoc node = type.getNode();
264       if (node != null)
265       {
266          if (JavaUtils.isTrueExplicitly(Utils.getAttribute(node, "abstract")))
267          {
268             return super.getClassModifiers() + "abstract ";
269          }
270       }
271       return super.getClassModifiers();
272    } // getClassModifiers
273

274    /**
275     * Returns the appropriate extends text
276     *
277     * @return "" or " extends <class> "
278     */

279    protected String JavaDoc getExtendsText()
280    {
281       // See if this class extends another class
282
String JavaDoc extendsText = "";
283       if (extendType != null && !type.isSimpleType() && extendType.getDimensions().length() == 0)
284       {
285          extendsText = " extends " + extendType.getName() + " ";
286       }
287       return extendsText;
288    }
289
290    /**
291     * Returns the appropriate implements text
292     *
293     * @return " implements <classes> "
294     */

295    protected String JavaDoc getImplementsText()
296    {
297       // See if this class extends another class
298
String JavaDoc implementsText = " implements java.io.Serializable";
299       if (type.isSimpleType())
300       {
301          implementsText += ", org.jboss.axis.encoding.SimpleType";
302       }
303       implementsText += " ";
304       return implementsText;
305    }
306
307    /**
308     * Writes the member fields.
309     */

310    protected void writeMemberFields()
311    {
312       // Define the member element of the bean
313
for (int i = 0; i < names.size(); i += 2)
314       {
315          String JavaDoc typeName = (String JavaDoc)names.get(i);
316          String JavaDoc variable = (String JavaDoc)names.get(i + 1);
317
318          // Declare the bean element
319
pw.print(" private " + typeName + " " + variable + ";");
320
321          // label the attribute fields.
322
if (elements == null || i >= (elements.size() * 2))
323             pw.println(" // attribute");
324          else
325             pw.println();
326       }
327       pw.println();
328    }
329
330    /**
331     * Writes the default constructor.
332     */

333    protected void writeDefaultConstructor()
334    {
335       // Define the default constructor
336
pw.println(" public " + className + "() {");
337       pw.println(" }");
338       pw.println();
339    }
340
341    /**
342     * Writes the full constructor.
343     * Note that this class is not recommended for
344     * JSR 101 compliant beans, but is provided for
345     * extended classes which may wish to generate a full
346     * constructor.
347     */

348    protected void writeFullConstructor()
349    {
350       // The constructor needs to consider all extended types
351
Vector JavaDoc extendList = new Vector JavaDoc();
352       extendList.add(type);
353       TypeEntry parent = extendType;
354       while (parent != null)
355       {
356          extendList.add(parent);
357          parent = SchemaUtils.getComplexElementExtensionBase(parent.getNode(),
358                  emitter.getSymbolTable());
359       }
360
361       // Now generate a list of names and types starting with
362
// the oldest parent. (Attrs are considered before elements).
363
Vector JavaDoc paramTypes = new Vector JavaDoc();
364       Vector JavaDoc paramNames = new Vector JavaDoc();
365       for (int i = extendList.size() - 1; i >= 0; i--)
366       {
367          TypeEntry te = (TypeEntry)extendList.elementAt(i);
368
369          // The names of the inherited parms are mangled
370
// in case they interfere with local parms.
371
String JavaDoc mangle = "";
372          if (i > 0)
373          {
374             mangle = "_" +
375                     Utils.xmlNameToJava(te.getQName().getLocalPart()) +
376                     "_";
377          }
378          // Process the attributes
379
Vector JavaDoc attributes = SchemaUtils.getContainedAttributeTypes(te.getNode(), emitter.getSymbolTable());
380          if (attributes != null)
381          {
382             for (int j = 0; j < attributes.size(); j += 2)
383             {
384                paramTypes.add(((TypeEntry)attributes.get(j)).getName());
385                String JavaDoc name = ((QName JavaDoc)attributes.get(j + 1)).getLocalPart();
386                paramNames.add(mangle + Utils.xmlNameToJava(name));
387             }
388          }
389          // Process the elements
390
Vector JavaDoc elements = SchemaUtils.getContainedElementDeclarations(te.getNode(), emitter.getSymbolTable());
391          if (elements != null)
392          {
393             for (int j = 0; j < elements.size(); j++)
394             {
395                ElementDecl elem = (ElementDecl)elements.get(j);
396                paramTypes.add(elem.getType().getName());
397                paramNames.add(mangle +
398                        Utils.xmlNameToJava(elem.getName().getLocalPart()));
399             }
400          }
401       }
402       // Set the index where the local params start
403
int localParams = paramTypes.size() - names.size() / 2;
404
405
406       // Now write the constructor signature
407
if (paramTypes.size() > 0)
408       {
409          pw.println(" public " + className + "(");
410          for (int i = 0; i < paramTypes.size(); i++)
411          {
412             pw.print(" " + paramTypes.elementAt(i) +
413                     " " + paramNames.elementAt(i));
414             if ((i + 1) < paramTypes.size())
415             {
416                pw.println(",");
417             }
418             else
419             {
420                pw.println(") {");
421             }
422          }
423
424          // Call the extended constructor to set inherited fields
425
if (extendType != null && localParams > 0)
426          {
427             pw.println(" super(");
428             for (int j = 0; j < localParams; j++)
429             {
430                pw.print(" " + paramNames.elementAt(j));
431                if ((j + 1) < localParams)
432                {
433                   pw.println(",");
434                }
435                else
436                {
437                   pw.println(");");
438                }
439             }
440          }
441          // Set local fields directly
442
for (int j = localParams; j < paramNames.size(); j++)
443          {
444             pw.println(" this." + paramNames.elementAt(j) +
445                     " = " + paramNames.elementAt(j) + ";");
446          }
447          pw.println(" }");
448          pw.println();
449       }
450    }
451
452    /**
453     * Writes the constructors for SimpleTypes.
454     * Writes a constructor accepting a string and
455     * a constructor accepting the simple java type.
456     */

457    protected void writeSimpleConstructors()
458    {
459       // If this is a simple type,need to emit a string
460
// constructor and a value construtor.
461
if (type.isSimpleType() && simpleValueType != null)
462       {
463          if (!simpleValueType.equals("java.lang.String"))
464          {
465             pw.println(" public " + className + "(" +
466                     simpleValueType + " value) {");
467             pw.println(" this.value = value;");
468             pw.println(" }");
469             pw.println();
470          }
471
472          pw.println(" // " + Messages.getMessage("needStringCtor"));
473          pw.println(" public " + className + "(java.lang.String value) {");
474          // Make sure we wrap base types with its Object type
475
String JavaDoc wrapper = JavaUtils.getWrapper(simpleValueType);
476
477          if (wrapper != null)
478          {
479             pw.println(" this.value = new " + wrapper +
480                     "(value)." + simpleValueType + "Value();");
481          }
482          else
483          {
484             if (simpleValueType.equals("byte[]"))
485             {
486                pw.println(" this.value = org.jboss.axis.types.HexBinary.decode(value);");
487             }
488             else if (simpleValueType.equals("org.jboss.axis.types.URI"))
489             {
490                pw.println(" try {");
491                pw.println(" this.value = new org.jboss.axis.types.URI(value);");
492                pw.println(" }");
493                pw.println(" catch (org.jboss.axis.types.URI.MalformedURIException mue) {");
494                pw.println(" this.value = new org.jboss.axis.types.URI();");
495                pw.println(" }");
496             }
497             else if (simpleValueType.equals("java.util.Date"))
498             {
499                pw.println(" try {");
500                pw.println(" this.value = (java.text.DateFormat.getDateTimeInstance()).parse(value);");
501                pw.println(" }");
502                pw.println(" catch (java.text.ParseException e){");
503                pw.println(" throw new java.lang.RuntimeException(e.toString());");
504                pw.println(" }");
505             }
506             else if (simpleValueType.equals("java.util.Calendar"))
507             {
508                pw.println(" java.util.Calendar cal = java.util.Calendar.getInstance();");
509                pw.println(" try {");
510                pw.println(" java.util.Date dt = (java.text.DateFormat.getDateTimeInstance()).parse(value);");
511                pw.println(" cal.setTime(dt);");
512                pw.println(" this.value = cal;");
513                pw.println(" }");
514                pw.println(" catch (java.text.ParseException e){");
515                pw.println(" throw new java.lang.RuntimeException(e.toString());");
516                pw.println(" }");
517             }
518             else
519             {
520                pw.println(" this.value = new " +
521                        simpleValueType + "(value);");
522             }
523          }
524          pw.println(" }");
525          pw.println();
526       }
527    }
528
529    /**
530     * Writes the toString method
531     * Currently the toString method is only written for
532     * simpleTypes.
533     */

534    protected void writeToStringMethod()
535    {
536       // If this is a simple type, emit a toString
537
if (type.isSimpleType() && simpleValueType != null)
538       {
539          pw.println(" // " + Messages.getMessage("needToString"));
540          String JavaDoc wrapper = JavaUtils.getWrapper(simpleValueType);
541          pw.println(" public java.lang.String toString() {");
542          if (wrapper != null)
543          {
544             pw.println(" return new " + wrapper + "(value).toString();");
545          }
546          else
547          {
548             if (simpleValueType.equals("byte[]"))
549             {
550                pw.println(" return value == null ? null : org.jboss.axis.types.HexBinary.encode(value);");
551             }
552             else
553             {
554                pw.println(" return value == null ? null : value.toString();");
555             }
556          }
557          pw.println(" }");
558          pw.println();
559       }
560    }
561
562    /**
563     * Writes the setter and getter methods
564     */

565    protected void writeAccessMethods()
566    {
567       int j = 0;
568       // Define getters and setters for the bean elements
569
for (int i = 0; i < names.size(); i += 2, j++)
570       {
571          String JavaDoc typeName = (String JavaDoc)names.get(i);
572          String JavaDoc name = (String JavaDoc)names.get(i + 1);
573          String JavaDoc capName = Utils.capitalizeFirstChar(name);
574
575          String JavaDoc get = "get";
576          if (typeName.equals("boolean"))
577             get = "is";
578
579          if (enableGetters)
580          {
581             pw.println(" public " + typeName + " " +
582                     get + capName + "() {");
583             pw.println(" return " + name + ";");
584             pw.println(" }");
585             pw.println();
586          }
587          if (enableSetters)
588          {
589             pw.println(" public void set" + capName + "(" +
590                     typeName + " " + name + ") {");
591             pw.println(" this." + name + " = " + name + ";");
592             pw.println(" }");
593             pw.println();
594          }
595
596          // If this is a special collection type, insert extra
597
// java code so that the serializer/deserializer can recognize
598
// the class. This is not JAX-RPC, and will be replaced with
599
// compliant code when JAX-RPC determines how to deal with this case.
600
// These signatures comply with Bean Indexed Properties which seems
601
// like the reasonable approach to take for collection types.
602
// (It may be more efficient to handle this with an ArrayList...but
603
// for the initial support it was easier to use an actual array.)
604
if (elements != null && j < elements.size())
605          {
606             ElementDecl elem = (ElementDecl)elements.get(j);
607             if (elem.getType().getQName().getLocalPart().indexOf("[") > 0)
608             {
609                String JavaDoc compName = typeName.substring(0, typeName.lastIndexOf("["));
610                if (enableGetters)
611                {
612                   pw.println(" public " + compName + " " + get + capName +
613                           "(int i) {");
614                   pw.println(" return " + name + "[i];");
615                   pw.println(" }");
616                   pw.println();
617                }
618                if (enableSetters)
619                {
620                   pw.println(" public void set" + capName + "(int i, " +
621                           compName + " value) {");
622                   // According to the section 7.2 of the JavaBeans
623
// specification, the indexed setter should not
624
// establish or grow the array. Thus the following
625
// code is not generated for compliance purposes.
626
/*
627                   int bracketIndex = typeName.indexOf("[");
628                   String newingName = typeName.substring(0, bracketIndex + 1);
629                   String newingSuffix = typeName.substring(bracketIndex + 1);
630
631                   pw.println(" if (this." + name + " == null ||");
632                   pw.println(" this." + name + ".length <= i) {");
633                   pw.println(" " + typeName + " a = new " +
634                              newingName + "i + 1" + newingSuffix + ";");
635                   pw.println(" if (this." + name + " != null) {");
636                   pw.println(" for(int j = 0; j < this." + name +
637                              ".length; j++)");
638                   pw.println(" a[j] = this." + name + "[j];");
639                   pw.println(" }");
640                   pw.println(" this." + name + " = a;");
641                   pw.println(" }");
642                   */

643                   pw.println(" this." + name + "[i] = value;");
644                   pw.println(" }");
645                   pw.println();
646                }
647             }
648          }
649       }
650    }
651
652    /**
653     * Writes a general purpose equals method
654     */

655    protected void writeEqualsMethod()
656    {
657
658       // The __equalsCalc field and synchronized method are necessary
659
// in case the object has direct or indirect references to itself.
660
pw.println(" private java.lang.Object __equalsCalc = null;");
661       pw.println(" public synchronized boolean equals(java.lang.Object obj) {");
662
663       // First do the general comparison checks
664
pw.println(" if (!(obj instanceof " + className + ")) return false;");
665       pw.println(" " + className + " other = (" + className + ") obj;");
666       pw.println(" if (obj == null) return false;");
667       pw.println(" if (this == obj) return true;");
668
669       // Have we been here before ? return true if yes otherwise false
670
pw.println(" if (__equalsCalc != null) {");
671       pw.println(" return (__equalsCalc == obj);");
672       pw.println(" }");
673       pw.println(" __equalsCalc = obj;");
674
675       // Before checking the elements, check equality of the super class
676
String JavaDoc truth = "true";
677       if (extendType != null && !type.isSimpleType())
678       {
679          truth = "super.equals(obj)";
680       }
681       pw.println(" boolean _equals;");
682       if (names.size() == 0)
683       {
684          pw.println(" _equals = " + truth + ";");
685       }
686       else
687       {
688          pw.println(" _equals = " + truth + " && ");
689          for (int i = 0; i < names.size(); i += 2)
690          {
691             String JavaDoc variableType = (String JavaDoc)names.get(i);
692             String JavaDoc variable = (String JavaDoc)names.get(i + 1);
693             String JavaDoc get = "get";
694
695             if (variableType.equals("boolean"))
696                get = "is";
697
698             if (variableType.equals("int") ||
699                     variableType.equals("long") ||
700                     variableType.equals("short") ||
701                     variableType.equals("float") ||
702                     variableType.equals("double") ||
703                     variableType.equals("boolean") ||
704                     variableType.equals("byte"))
705             {
706                pw.print(" this." + variable + " == other." + get +
707                        Utils.capitalizeFirstChar(variable) + "()");
708             }
709             else if (variableType.indexOf("[") >= 0)
710             {
711                // Use java.util.Arrays.equals to compare arrays.
712
pw.println(" ((this." + variable +
713                        "==null && other." + get +
714                        Utils.capitalizeFirstChar(variable) + "()==null) || ");
715                pw.println(" (this." + variable + "!=null &&");
716                pw.print(" java.util.Arrays.equals(this." + variable +
717                        ", other." + get +
718                        Utils.capitalizeFirstChar(variable) + "())))");
719
720             }
721             else
722             {
723                pw.println(" ((this." + variable +
724                        "==null && other." + get +
725                        Utils.capitalizeFirstChar(variable) + "()==null) || ");
726                pw.println(" (this." + variable + "!=null &&");
727                pw.print(" this." + variable +
728                        ".equals(other." + get +
729                        Utils.capitalizeFirstChar(variable) + "())))");
730             }
731             if (i == (names.size() - 2))
732                pw.println(";");
733             else
734                pw.println(" &&");
735          }
736       }
737       pw.println(" __equalsCalc = null;");
738       pw.println(" return _equals;");
739       pw.println(" }");
740       pw.println("");
741    }
742
743    /**
744     * Writes a general purpose hashCode method.
745     */

746    protected void writeHashCodeMethod()
747    {
748       // The __hashCodeCalc field and synchronized method are necessary
749
// in case the object has direct or indirect references to itself.
750
pw.println(" private boolean __hashCodeCalc = false;");
751       pw.println(" public synchronized int hashCode() {");
752       pw.println(" if (__hashCodeCalc) {");
753       pw.println(" return 0;");
754       pw.println(" }");
755       pw.println(" __hashCodeCalc = true;");
756
757       // Get the hashCode of the super class
758
String JavaDoc start = "1";
759       if (extendType != null && !type.isSimpleType())
760       {
761          start = "super.hashCode()";
762       }
763       pw.println(" int _hashCode = " + start + ";");
764       for (int i = 0; i < names.size(); i += 2)
765       {
766          String JavaDoc variableType = (String JavaDoc)names.get(i);
767          String JavaDoc variable = (String JavaDoc)names.get(i + 1);
768          String JavaDoc get = "get";
769
770          if (variableType.equals("boolean"))
771             get = "is";
772
773          if (variableType.equals("int") ||
774                  variableType.equals("short") ||
775                  variableType.equals("byte"))
776          {
777             pw.println(" _hashCode += " + get +
778                     Utils.capitalizeFirstChar(variable) + "();");
779          }
780          else if (variableType.equals("boolean"))
781          {
782             pw.println(" _hashCode += new Boolean(" + get +
783                     Utils.capitalizeFirstChar(variable) + "()).hashCode();");
784          }
785          else if (variableType.equals("long"))
786          {
787             pw.println(" _hashCode += new Long(" + get +
788                     Utils.capitalizeFirstChar(variable) + "()).hashCode();");
789          }
790          else if (variableType.equals("float"))
791          {
792             pw.println(" _hashCode += new Float(" + get +
793                     Utils.capitalizeFirstChar(variable) + "()).hashCode();");
794          }
795          else if (variableType.equals("double"))
796          {
797             pw.println(" _hashCode += new Double(" + get +
798                     Utils.capitalizeFirstChar(variable) + "()).hashCode();");
799          }
800          else if (variableType.indexOf("[") >= 0)
801          {
802             // The hashCode calculation for arrays is complicated.
803
// Wish there was a hashCode method in java.utils.Arrays !
804
// Get the hashCode for each element of the array which is not an array.
805
pw.println(" if (" + get +
806                     Utils.capitalizeFirstChar(variable) + "() != null) {");
807             pw.println(" for (int i=0;");
808             pw.println(" i<java.lang.reflect.Array.getLength(" + get +
809                     Utils.capitalizeFirstChar(variable) + "());");
810             pw.println(" i++) {");
811             pw.println(" java.lang.Object obj = java.lang.reflect.Array.get(" +
812                     get +
813                     Utils.capitalizeFirstChar(variable) + "(), i);");
814             pw.println(" if (obj != null &&");
815             pw.println(" !obj.getClass().isArray()) {");
816             pw.println(" _hashCode += obj.hashCode();");
817             pw.println(" }");
818             pw.println(" }");
819             pw.println(" }");
820          }
821          else
822          {
823             pw.println(" if (" + get +
824                     Utils.capitalizeFirstChar(variable) + "() != null) {");
825             pw.println(" _hashCode += " + get +
826                     Utils.capitalizeFirstChar(variable) + "().hashCode();");
827             pw.println(" }");
828          }
829       }
830       // Reset the __hashCodeCalc variable and return
831
pw.println(" __hashCodeCalc = false;");
832       pw.println(" return _hashCode;");
833       pw.println(" }");
834       pw.println("");
835    }
836 } // class JavaBeanWriter
837
Popular Tags