View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation ("Software"), with or
3    * without modification, are permitted provided that the following conditions are met:
4    *
5    * 1. Redistributions of source code must retain copyright statements and notices. Redistributions
6    * must also contain a copy of this document.
7    *
8    * 2. Redistributions in binary form must reproduce the above copyright notice, this list of
9    * conditions and the following disclaimer in the documentation and/or other materials provided with
10   * the distribution.
11   *
12   * 3. The name "Exolab" must not be used to endorse or promote products derived from this Software
13   * without prior written permission of Intalio, Inc. For written permission, please contact
14   * info@exolab.org.
15   *
16   * 4. Products derived from this Software may not be called "Exolab" nor may "Exolab" appear in
17   * their names without prior written permission of Intalio, Inc. Exolab is a registered trademark of
18   * Intalio, Inc.
19   *
20   * 5. Due credit should be given to the Exolab Project (http://www.exolab.org/).
21   *
22   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR
23   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
24   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL INTALIO, INC. OR ITS
25   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28   * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
29   * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30   *
31   * Copyright 1999-2002 (C) Intalio Inc. All Rights Reserved.
32   *
33   * $Id$
34   */
35  package org.exolab.castor.builder;
36  
37  import java.util.Enumeration;
38  
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.exolab.castor.builder.types.XSAnyURI;
42  import org.exolab.castor.builder.types.XSBase64Binary;
43  import org.exolab.castor.builder.types.XSBoolean;
44  import org.exolab.castor.builder.types.XSByte;
45  import org.exolab.castor.builder.types.XSClass;
46  import org.exolab.castor.builder.types.XSDate;
47  import org.exolab.castor.builder.types.XSDateTime;
48  import org.exolab.castor.builder.types.XSDecimal;
49  import org.exolab.castor.builder.types.XSDouble;
50  import org.exolab.castor.builder.types.XSDuration;
51  import org.exolab.castor.builder.types.XSFloat;
52  import org.exolab.castor.builder.types.XSGDay;
53  import org.exolab.castor.builder.types.XSGMonth;
54  import org.exolab.castor.builder.types.XSGMonthDay;
55  import org.exolab.castor.builder.types.XSGYear;
56  import org.exolab.castor.builder.types.XSGYearMonth;
57  import org.exolab.castor.builder.types.XSHexBinary;
58  import org.exolab.castor.builder.types.XSId;
59  import org.exolab.castor.builder.types.XSIdRef;
60  import org.exolab.castor.builder.types.XSIdRefs;
61  import org.exolab.castor.builder.types.XSInt;
62  import org.exolab.castor.builder.types.XSInteger;
63  import org.exolab.castor.builder.types.XSLong;
64  import org.exolab.castor.builder.types.XSNCName;
65  import org.exolab.castor.builder.types.XSNMToken;
66  import org.exolab.castor.builder.types.XSNMTokens;
67  import org.exolab.castor.builder.types.XSNegativeInteger;
68  import org.exolab.castor.builder.types.XSNonNegativeInteger;
69  import org.exolab.castor.builder.types.XSNonPositiveInteger;
70  import org.exolab.castor.builder.types.XSNormalizedString;
71  import org.exolab.castor.builder.types.XSPositiveInteger;
72  import org.exolab.castor.builder.types.XSQName;
73  import org.exolab.castor.builder.types.XSShort;
74  import org.exolab.castor.builder.types.XSString;
75  import org.exolab.castor.builder.types.XSTime;
76  import org.exolab.castor.builder.types.XSType;
77  import org.exolab.castor.builder.types.XSUnsignedByte;
78  import org.exolab.castor.builder.types.XSUnsignedInt;
79  import org.exolab.castor.builder.types.XSUnsignedLong;
80  import org.exolab.castor.builder.types.XSUnsignedShort;
81  import org.exolab.castor.xml.schema.AttributeDecl;
82  import org.exolab.castor.xml.schema.ElementDecl;
83  import org.exolab.castor.xml.schema.Facet;
84  import org.exolab.castor.xml.schema.Schema;
85  import org.exolab.castor.xml.schema.SimpleType;
86  import org.exolab.castor.xml.schema.SimpleTypesFactory;
87  import org.exolab.castor.xml.schema.Structure;
88  import org.exolab.castor.xml.schema.Union;
89  import org.exolab.javasource.JClass;
90  import org.exolab.javasource.JNaming;
91  import org.exolab.javasource.JType;
92  
93  /**
94   * A class used to convert XML Schema SimpleTypes into the appropriate XSType.
95   * 
96   * @author <a href="mailto:kvisco@intalio.com">Keith Visco</a>
97   * @author <a href="mailto:blandin@intalio.com">Arnaud Blandin</a>
98   * @version $Revision$ $Date: 2006-01-21 04:43:28 -0700 (Sat, 21 Jan 2006) $
99   */
100 public final class TypeConversion {
101 
102   /** Jakarta's common-logging logger. */
103   private static final Log LOG = LogFactory.getLog(TypeConversion.class);
104 
105   /** Configuration for our source generator. */
106   private final BuilderConfiguration _config;
107 
108   /**
109    * Creates a new TypeConversion instance.
110    *
111    * @param config the BuilderConfiguration instance (must not be null).
112    */
113   public TypeConversion(final BuilderConfiguration config) {
114     if (config == null) {
115       String error = "The argument 'config' must not be null.";
116       throw new IllegalArgumentException(error);
117     }
118     _config = config;
119   } // -- TypeConversion
120 
121   /**
122    * Converts the given Simpletype to the appropriate XSType.
123    *
124    * @param simpleType the SimpleType to convert to an XSType instance
125    * @param useJava50 true if source code is to be generated for Java 5
126    * @return the XSType which represets the given Simpletype
127    */
128   public XSType convertType(final SimpleType simpleType, final boolean useJava50) {
129     return convertType(simpleType, null, useJava50);
130   }
131 
132   /**
133    * Converts the given Simpletype to the appropriate XSType.
134    *
135    * @param simpleType the SimpleType to convert to an XSType instance
136    * @param packageName the packageName for any new class types
137    * @param useJava50 true if source code is to be generated for Java 5
138    * @return the XSType which represets the given Simpletype
139    */
140   public XSType convertType(final SimpleType simpleType, final String packageName,
141       final boolean useJava50) {
142     return convertType(simpleType, packageName, _config.usePrimitiveWrapper(), useJava50, null);
143   }
144 
145   /**
146    * Converts the given Simpletype to the appropriate XSType.
147    *
148    * @param simpleType the SimpleType to convert to an XSType instance
149    * @param packageName the packageName for any new class types
150    * @param useWrapper a boolean that when true indicates that primitive wrappers be used instead of
151    *        the actual primitives (e.g. java.lang.Integer instead of int)
152    * @param useJava50 true if source code is to be generated for Java 5
153    * @param javaClassBindingName valid java Class Name specified by corresponding binding component
154    * @return the XSType which represets the given Simpletype
155    */
156   public XSType convertType(final SimpleType simpleType, final String packageName,
157       final boolean useWrapper, final boolean useJava50, final String javaClassBindingName) {
158     if (simpleType == null) {
159       return null;
160     }
161 
162     XSType xsType = null;
163     // -- determine base type
164     SimpleType base = simpleType;
165 
166     while ((base != null) && (!base.isBuiltInType())) {
167       base = (SimpleType) base.getBaseType();
168     }
169 
170     // try to find a common type for UNIONs, and use it; if not,
171     // use 'java.lang.Object' instead.
172     if (simpleType.getStructureType() == Structure.UNION) {
173       return convertUnion(simpleType, packageName, useWrapper, useJava50);
174     } else if (base == null) {
175       String className = _config.getJavaNaming().toJavaClassName(simpleType.getName());
176       return new XSClass(new JClass(className));
177     }
178 
179     xsType = findXSTypeForEnumeration(simpleType, packageName, javaClassBindingName);
180     if (xsType != null) {
181       return xsType;
182     }
183 
184     // If we don't have the XSType yet, we have to look at the Type Code
185 
186     switch (base.getTypeCode()) {
187       case SimpleTypesFactory.ID_TYPE: // -- ID
188         return new XSId();
189       case SimpleTypesFactory.IDREF_TYPE: // -- IDREF
190         return new XSIdRef();
191       case SimpleTypesFactory.IDREFS_TYPE: // -- IDREFS
192         return new XSIdRefs(SourceGeneratorConstants.FIELD_INFO_VECTOR, useJava50);
193       case SimpleTypesFactory.NMTOKEN_TYPE: // -- NMTOKEN
194         XSNMToken xsNMToken = new XSNMToken();
195         xsNMToken.setFacets(simpleType);
196         return xsNMToken;
197       case SimpleTypesFactory.NMTOKENS_TYPE: // -- NMTOKENS
198         return new XSNMTokens(SourceGeneratorConstants.FIELD_INFO_VECTOR, useJava50);
199       case SimpleTypesFactory.ANYURI_TYPE: // --AnyURI
200         return new XSAnyURI();
201       case SimpleTypesFactory.BASE64BINARY_TYPE: // -- base64Bbinary
202         return new XSBase64Binary(useJava50);
203       case SimpleTypesFactory.HEXBINARY_TYPE: // -- hexBinary
204         return new XSHexBinary(useJava50);
205       case SimpleTypesFactory.BOOLEAN_TYPE: // -- boolean
206         return new XSBoolean(useWrapper);
207       case SimpleTypesFactory.BYTE_TYPE: // --byte
208         XSByte xsByte = new XSByte(useWrapper);
209         if (!simpleType.isBuiltInType()) {
210           xsByte.setFacets(simpleType);
211         }
212         return xsByte;
213       case SimpleTypesFactory.DATE_TYPE: // -- date
214         XSDate xsDate = new XSDate();
215         if (!simpleType.isBuiltInType()) {
216           xsDate.setFacets(simpleType);
217         }
218         return xsDate;
219       case SimpleTypesFactory.DATETIME_TYPE: // -- dateTime
220         XSDateTime xsDateTime = new XSDateTime();
221         if (!simpleType.isBuiltInType()) {
222           xsDateTime.setFacets(simpleType);
223         }
224         return xsDateTime;
225       case SimpleTypesFactory.DOUBLE_TYPE: // -- double
226         XSDouble xsDouble = new XSDouble(useWrapper);
227         if (!simpleType.isBuiltInType()) {
228           xsDouble.setFacets(simpleType);
229         }
230         return xsDouble;
231       case SimpleTypesFactory.DURATION_TYPE: // -- duration
232         XSDuration xsDuration = new XSDuration();
233         if (!simpleType.isBuiltInType()) {
234           xsDuration.setFacets(simpleType);
235         }
236         return xsDuration;
237       case SimpleTypesFactory.DECIMAL_TYPE: // -- decimal
238         XSDecimal xsDecimal = new XSDecimal();
239         if (!simpleType.isBuiltInType()) {
240           xsDecimal.setFacets(simpleType);
241         }
242         return xsDecimal;
243       case SimpleTypesFactory.FLOAT_TYPE: // -- float
244         XSFloat xsFloat = new XSFloat(useWrapper);
245         if (!simpleType.isBuiltInType()) {
246           xsFloat.setFacets(simpleType);
247         }
248         return xsFloat;
249       case SimpleTypesFactory.GDAY_TYPE: // --GDay
250         XSGDay xsGDay = new XSGDay();
251         if (!simpleType.isBuiltInType()) {
252           xsGDay.setFacets(simpleType);
253         }
254         return xsGDay;
255       case SimpleTypesFactory.GMONTHDAY_TYPE: // --GMonthDay
256         XSGMonthDay xsGMonthDay = new XSGMonthDay();
257         if (!simpleType.isBuiltInType()) {
258           xsGMonthDay.setFacets(simpleType);
259         }
260         return xsGMonthDay;
261       case SimpleTypesFactory.GMONTH_TYPE: // --GMonth
262         XSGMonth xsGMonth = new XSGMonth();
263         if (!simpleType.isBuiltInType()) {
264           xsGMonth.setFacets(simpleType);
265         }
266         return xsGMonth;
267       case SimpleTypesFactory.GYEARMONTH_TYPE: // --GYearMonth
268         XSGYearMonth xsGYearMonth = new XSGYearMonth();
269         if (!simpleType.isBuiltInType()) {
270           xsGYearMonth.setFacets(simpleType);
271         }
272         return xsGYearMonth;
273       case SimpleTypesFactory.GYEAR_TYPE: // --GYear
274         XSGYear xsGYear = new XSGYear();
275         if (!simpleType.isBuiltInType()) {
276           xsGYear.setFacets(simpleType);
277         }
278         return xsGYear;
279       case SimpleTypesFactory.INTEGER_TYPE: // -- integer
280         XSInteger xsInteger = new XSInteger(useWrapper);
281         if (!simpleType.isBuiltInType()) {
282           xsInteger.setFacets(simpleType);
283         }
284         return xsInteger;
285       case SimpleTypesFactory.INT_TYPE: // -- int
286         XSInt xsInt = new XSInt(useWrapper);
287         if (!simpleType.isBuiltInType()) {
288           xsInt.setFacets(simpleType);
289         }
290         return xsInt;
291       case SimpleTypesFactory.LANGUAGE_TYPE: // -- Language
292         // -- since we don't actually support this type, yet, we'll simply treat
293         // -- it as a string, but warn the user.
294         LOG.warn("Warning: Currently, the W3C datatype '" + simpleType.getName()
295             + "' is supported only as a String by Castor Source Generator.");
296         return new XSString();
297       case SimpleTypesFactory.LONG_TYPE: // -- long
298         XSLong xsLong = new XSLong(useWrapper);
299         if (!simpleType.isBuiltInType()) {
300           xsLong.setFacets(simpleType);
301         }
302         return xsLong;
303       case SimpleTypesFactory.NCNAME_TYPE: // --NCName
304         return new XSNCName();
305       case SimpleTypesFactory.NON_POSITIVE_INTEGER_TYPE: // -- nonPositiveInteger
306         XSNonPositiveInteger xsNPInteger = new XSNonPositiveInteger(useWrapper);
307         xsNPInteger.setFacets(simpleType);
308         return xsNPInteger;
309       case SimpleTypesFactory.NON_NEGATIVE_INTEGER_TYPE: // -- nonNegativeInteger
310         XSNonNegativeInteger xsNNInteger = new XSNonNegativeInteger(useWrapper);
311         xsNNInteger.setFacets(simpleType);
312         return xsNNInteger;
313       case SimpleTypesFactory.NEGATIVE_INTEGER_TYPE: // -- negative-integer
314         XSNegativeInteger xsNInteger = new XSNegativeInteger(useWrapper);
315         xsNInteger.setFacets(simpleType);
316         return xsNInteger;
317       case SimpleTypesFactory.UNSIGNED_INT_TYPE: // -- unsigned-integer
318         XSUnsignedInt xsUnsignedInt = new XSUnsignedInt(useWrapper);
319         xsUnsignedInt.setFacets(simpleType);
320         return xsUnsignedInt;
321       case SimpleTypesFactory.UNSIGNED_SHORT_TYPE: // -- unsigned-short
322         XSUnsignedShort xsUnsignedShort = new XSUnsignedShort(useWrapper);
323         xsUnsignedShort.setFacets(simpleType);
324         return xsUnsignedShort;
325       case SimpleTypesFactory.UNSIGNED_BYTE_TYPE: // -- unsigned-byte
326         XSUnsignedByte xsUnsignedByte = new XSUnsignedByte(useWrapper);
327         xsUnsignedByte.setFacets(simpleType);
328         return xsUnsignedByte;
329       case SimpleTypesFactory.UNSIGNED_LONG_TYPE: // -- unsigned-long
330         XSUnsignedLong xsUnsignedLong = new XSUnsignedLong();
331         xsUnsignedLong.setFacets(simpleType);
332         return xsUnsignedLong;
333       case SimpleTypesFactory.NORMALIZEDSTRING_TYPE: // -- normalizedString
334         XSNormalizedString xsNormalString = new XSNormalizedString();
335         if (!simpleType.isBuiltInType()) {
336           xsNormalString.setFacets(simpleType);
337         }
338         return xsNormalString;
339       case SimpleTypesFactory.POSITIVE_INTEGER_TYPE: // -- positive-integer
340         XSPositiveInteger xsPInteger = new XSPositiveInteger(useWrapper);
341         xsPInteger.setFacets(simpleType);
342         return xsPInteger;
343       case SimpleTypesFactory.QNAME_TYPE: // -- QName
344         XSQName xsQName = new XSQName();
345         xsQName.setFacets(simpleType);
346         return xsQName;
347       case SimpleTypesFactory.STRING_TYPE: // -- string
348         xsType = findXSTypeForEnumeration(simpleType, packageName, javaClassBindingName);
349         if (xsType == null) {
350           // Not an enumerated String type
351           XSString xsString = new XSString();
352           if (!simpleType.isBuiltInType()) {
353             xsString.setFacets(simpleType);
354           }
355           xsType = xsString;
356         }
357         break;
358       case SimpleTypesFactory.SHORT_TYPE: // -- short
359         XSShort xsShort = new XSShort(useWrapper);
360         if (!simpleType.isBuiltInType()) {
361           xsShort.setFacets(simpleType);
362         }
363         return xsShort;
364       case SimpleTypesFactory.TIME_TYPE: // -- time
365         XSTime xsTime = new XSTime();
366         if (!simpleType.isBuiltInType()) {
367           xsTime.setFacets(simpleType);
368         }
369         return xsTime;
370       case SimpleTypesFactory.TOKEN_TYPE: // -- token
371         // -- since we don't actually support this type, yet, we'll simply treat
372         // -- it as a string, but warn the user.
373         LOG.warn("Warning: Currently, the W3C datatype 'token'"
374             + " is supported only as a String by Castor Source Generator.");
375         XSString xsString = new XSString();
376         if (!simpleType.isBuiltInType()) {
377           xsString.setFacets(simpleType);
378         }
379         return xsString;
380       default: // -- error
381         String name = simpleType.getName();
382         if (name == null || name.length() == 0) {
383           // --we know it is a restriction
384           name = simpleType.getBuiltInBaseType().getName();
385         }
386 
387         LOG.warn("Warning: The W3C datatype '" + name + "' "
388             + "is not currently supported by Castor Source Generator.");
389         String className = _config.getJavaNaming().toJavaClassName(name);
390         xsType = new XSClass(new JClass(className));
391         break;
392     }
393 
394     return xsType;
395   } // -- convertType
396 
397   /**
398    * Converts the given XML schema Union type to the appropriate XSType.
399    *
400    * @param simpleType the SimpleType to convert to an XSType instance
401    * @param packageName the packageName for any new class types
402    * @param useJava50 true if source code is to be generated for Java 5
403    * @param useWrapper indicates whether primitive wrappers should be used instead of the actual
404    *        primitives (e.g. java.lang.Integer instead of int)
405    * @return the XSType which represets the given Simpletype
406    */
407   private XSType convertUnion(final SimpleType simpleType, final String packageName,
408       final boolean useWrapper, final boolean useJava50) {
409     SimpleType currentUnion = simpleType;
410     SimpleType common = findCommonType((Union) currentUnion);
411     // look at type hierarchy (if any), and try to
412     // find a common type recursively
413     while (common == null && currentUnion.getBaseType() != null
414         && currentUnion.getBaseType().getStructureType() == Structure.UNION) {
415       currentUnion = (SimpleType) currentUnion.getBaseType();
416       common = findCommonType((Union) currentUnion);
417     }
418     if (common == null) {
419       return new XSClass(SGTypes.OBJECT);
420     }
421 
422     XSType convertedType = convertType(common, packageName, useWrapper, useJava50, null);
423     Union unionType = (Union) simpleType;
424     Enumeration<SimpleType> memberTypes = unionType.getMemberTypes();
425     while (memberTypes.hasMoreElements()) {
426       SimpleType memberType = memberTypes.nextElement();
427       convertedType.setFacets(memberType);
428     }
429     return convertedType;
430   }
431 
432   /**
433    * Returns the XSType that corresponds to the given javaType.
434    * 
435    * @param javaType name of the Java type for which to look up the XSType
436    * @return XSType that corresponds to the given javaType
437    */
438   public static XSType convertType(final String javaType) {
439     if (javaType == null) {
440       return null;
441     }
442 
443     // --Boolean
444     if (javaType.equals(TypeNames.BOOLEAN_OBJECT)) {
445       return new XSBoolean(true);
446     } else if (javaType.equals(TypeNames.BOOLEAN_PRIMITIVE)) {
447       return new XSBoolean(false);
448     } else if (javaType.equals(TypeNames.BYTE_OBJECT)) {
449       return new XSByte(true);
450     } else if (javaType.equals(TypeNames.BYTE_PRIMITIVE)) {
451       return new XSBoolean(false);
452     } else if (javaType.equals(TypeNames.CASTOR_DATE)) {
453       return new XSDateTime();
454     } else if (javaType.equals(TypeNames.CASTOR_DURATION)) {
455       return new XSDuration();
456     } else if (javaType.equals(TypeNames.CASTOR_GDAY)) {
457       return new XSGDay();
458     } else if (javaType.equals(TypeNames.CASTOR_GMONTH)) {
459       return new XSGMonth();
460     } else if (javaType.equals(TypeNames.CASTOR_GMONTHDAY)) {
461       return new XSGMonthDay();
462     } else if (javaType.equals(TypeNames.CASTOR_GYEAR)) {
463       return new XSGYear();
464     } else if (javaType.equals(TypeNames.CASTOR_GYEARMONTH)) {
465       return new XSGYearMonth();
466     } else if (javaType.equals(TypeNames.CASTOR_TIME)) {
467       return new XSTime();
468     } else if (javaType.equals(TypeNames.DATE)) {
469       return new XSDate();
470     } else if (javaType.equals(TypeNames.DECIMAL)) {
471       return new XSDecimal();
472     } else if (javaType.equals(TypeNames.DOUBLE_OBJECT)) {
473       return new XSDouble(true);
474     } else if (javaType.equals(TypeNames.DOUBLE_PRIMITIVE)) {
475       return new XSDouble(false);
476     } else if (javaType.equals(TypeNames.FLOAT_OBJECT)) {
477       return new XSFloat(true);
478     } else if (javaType.equals(TypeNames.FLOAT_PRIMITIVE)) {
479       return new XSDouble(false);
480     } else if (javaType.equals(TypeNames.INTEGER)) {
481       return new XSInteger(true);
482     } else if (javaType.equals(TypeNames.INT)) {
483       return new XSInt();
484     } else if (javaType.equals(TypeNames.SHORT_OBJECT)) {
485       return new XSShort(true);
486     } else if (javaType.equals(TypeNames.SHORT_PRIMITIVE)) {
487       return new XSShort(false);
488     } else if (javaType.equals(TypeNames.STRING)) {
489       return new XSString();
490     }
491 
492     // --no XSType implemented for it we return a XSClass
493     return new XSClass(new JClass(javaType));
494   }
495 
496   /**
497    * Returns an XSType for an enumerated type. For non-enumerated types, returns null.
498    * 
499    * @param simpleType the SimpleType being inspected
500    * @param packageName current package name
501    * @param javaClassBindingName valid Java Class Name specified by corresponding binding component
502    * @return an XSType for an enumerated type, null for a non-enumerated type.
503    */
504   private XSType findXSTypeForEnumeration(final SimpleType simpleType, final String packageName,
505       final String javaClassBindingName) {
506     if (!simpleType.hasFacet(Facet.ENUMERATION)) {
507       return null;
508     }
509 
510     XSType xsType = null;
511     String typeName = simpleType.getName();
512 
513     // -- anonymous type
514     if (typeName == null) {
515       if (javaClassBindingName != null) {
516         // handled by binding file
517         if (!JNaming.isInJavaLang(javaClassBindingName)
518             && !JNaming.isReservedByCastor(javaClassBindingName)
519             && !JNaming.isReservedByWindows(javaClassBindingName)) {
520           typeName = javaClassBindingName;
521           // typeName += "Type";
522         }
523       }
524     }
525 
526     if (typeName == null) {
527       // not handled by binding file
528       Structure parent = simpleType.getParent();
529       if (parent instanceof ElementDecl) {
530         typeName = ((ElementDecl) parent).getName();
531       } else if (parent instanceof AttributeDecl) {
532         typeName = ((AttributeDecl) parent).getName();
533       }
534 
535       typeName = typeName + "Type";
536     }
537 
538     String className = _config.getJavaNaming().toJavaClassName(typeName);
539 
540     // Get the appropriate package name for this type
541     String typePackageName = packageName;
542     if (typePackageName == null) {
543       String ns = simpleType.getSchema().getTargetNamespace();
544       typePackageName = _config.lookupPackageByNamespace(ns);
545     }
546 
547     if (typePackageName != null && typePackageName.length() > 0) {
548       typePackageName = typePackageName + '.' + SourceGeneratorConstants.TYPES_PACKAGE;
549     } else {
550       typePackageName = SourceGeneratorConstants.TYPES_PACKAGE;
551     }
552 
553     className = typePackageName + '.' + className;
554 
555     xsType = new XSClass(new JClass(className));
556     xsType.setAsEnumerated(true);
557 
558     return xsType;
559   }
560 
561   /**
562    * Returns the common type for the Union, or null if no common type exists among the members of
563    * the Union.
564    *
565    * @param union the Union to return the common type for
566    * @return the common SimpleType for the Union.
567    */
568   private static SimpleType findCommonType(final Union union) {
569     SimpleType common = null;
570     Enumeration<SimpleType> enumeration = union.getMemberTypes();
571     while (enumeration.hasMoreElements()) {
572       SimpleType type = enumeration.nextElement();
573       type = type.getBuiltInBaseType();
574       if (common == null) {
575         common = type;
576       } else {
577         common = findCommonType(common, type);
578         // -- no common types
579         if (common == null) {
580           break;
581         }
582       }
583     }
584     return common;
585   } // -- findCommonType
586 
587   /**
588    * Compares the two SimpleTypes. The lowest common ancestor of both types will be returned,
589    * otherwise null is returned if the types are not compatible.
590    *
591    * @param aType the first type to compare
592    * @param bType the second type to compare
593    * @return the common ancestor of both types if there is one, null if the types are not
594    *         compatible.
595    */
596   private static SimpleType findCommonType(final SimpleType aType, final SimpleType bType) {
597     int type1 = aType.getTypeCode();
598     int type2 = bType.getTypeCode();
599 
600     if (type1 == type2) {
601       return aType;
602     }
603 
604     if (isNumeric(aType) && isNumeric(bType)) {
605       // TODO Finish this so we can implement Unions
606     } else if (isString(aType) && isString(bType)) {
607       // TODO Finish this so we can implement Unions
608     }
609 
610     // -- Just return string for now, as all simpleTypes can fit into a string
611     Schema schema = aType.getSchema();
612     return schema.getSimpleType("string", schema.getSchemaNamespace());
613   }
614 
615   /**
616    * Returns true if this simpletype is numeric.
617    * 
618    * @param type the type to be examined
619    * @return true if this simpletype is numeric.
620    */
621   private static boolean isNumeric(final SimpleType type) {
622     int code = type.getTypeCode();
623     switch (code) {
624       case SimpleTypesFactory.BYTE_TYPE:
625       case SimpleTypesFactory.DOUBLE_TYPE:
626       case SimpleTypesFactory.DECIMAL_TYPE:
627       case SimpleTypesFactory.FLOAT_TYPE:
628       case SimpleTypesFactory.INTEGER_TYPE:
629       case SimpleTypesFactory.INT_TYPE:
630       case SimpleTypesFactory.LONG_TYPE:
631       case SimpleTypesFactory.NON_POSITIVE_INTEGER_TYPE:
632       case SimpleTypesFactory.NON_NEGATIVE_INTEGER_TYPE:
633       case SimpleTypesFactory.NEGATIVE_INTEGER_TYPE:
634       case SimpleTypesFactory.POSITIVE_INTEGER_TYPE:
635       case SimpleTypesFactory.SHORT_TYPE:
636         return true;
637       default:
638         return false;
639     }
640   } // -- isNumeric
641 
642   /**
643    * Returns true if this simpletype is a String.
644    * 
645    * @param type the type to be examined
646    * @return true if this simpletype is String.
647    */
648   private static boolean isString(final SimpleType type) {
649     int code = type.getTypeCode();
650     switch (code) {
651       // -- string types
652       case SimpleTypesFactory.ANYURI_TYPE:
653       case SimpleTypesFactory.ID_TYPE:
654       case SimpleTypesFactory.IDREF_TYPE:
655       case SimpleTypesFactory.IDREFS_TYPE:
656       case SimpleTypesFactory.LANGUAGE_TYPE:
657       case SimpleTypesFactory.NCNAME_TYPE:
658       case SimpleTypesFactory.NMTOKEN_TYPE:
659       case SimpleTypesFactory.NMTOKENS_TYPE:
660       case SimpleTypesFactory.NORMALIZEDSTRING_TYPE:
661       case SimpleTypesFactory.STRING_TYPE:
662       case SimpleTypesFactory.QNAME_TYPE:
663         return true;
664       default:
665         return false;
666     }
667   } // -- isString
668 
669   /**
670    * Constants.
671    */
672   protected static class TypeNames {
673     protected static final String BOOLEAN_PRIMITIVE = JType.BOOLEAN.getName();
674     protected static final String BOOLEAN_OBJECT = JType.BOOLEAN.getWrapperName();
675     protected static final String BYTE_PRIMITIVE = JType.BYTE.getName();
676     protected static final String BYTE_OBJECT = JType.BYTE.getWrapperName();
677     protected static final String DATE = "java.util.Date";
678     protected static final String CASTOR_DATE = "org.exolab.castor.types.Date";
679     protected static final String CASTOR_TIME = "org.exolab.castor.types.Time";
680     protected static final String CASTOR_DURATION = "org.exolab.castor.types.Duration";
681     protected static final String CASTOR_GMONTH = "org.exolab.castor.types.GMonth";
682     protected static final String CASTOR_GMONTHDAY = "org.exolab.castor.types.GMonthDay";
683     protected static final String CASTOR_GYEAR = "org.exolab.castor.types.GYear";
684     protected static final String CASTOR_GYEARMONTH = "org.exolab.castor.types.GYearMonth";
685     protected static final String CASTOR_GDAY = "org.exolab.castor.types.GDay";
686     protected static final String DECIMAL = "java.math.BigDecimal";
687     protected static final String DOUBLE_PRIMITIVE = JType.DOUBLE.getName();
688     protected static final String DOUBLE_OBJECT = JType.DOUBLE.getWrapperName();
689     protected static final String FLOAT_PRIMITIVE = JType.FLOAT.getName();
690     protected static final String FLOAT_OBJECT = JType.FLOAT.getWrapperName();
691     protected static final String INT = JType.INT.getName();
692     protected static final String INTEGER = JType.INT.getWrapperName();
693     protected static final String SHORT_PRIMITIVE = JType.SHORT.getName();
694     protected static final String SHORT_OBJECT = JType.SHORT.getWrapperName();
695     protected static final String STRING = "java.lang.String";
696   }
697 
698 } // -- TypeConversion