View Javadoc
1   /*
2    * Redistribution and use of this software and associated documentation
3    * ("Software"), with or without modification, are permitted provided
4    * that the following conditions are met:
5    *
6    * 1. Redistributions of source code must retain copyright
7    *    statements and notices.  Redistributions must also contain a
8    *    copy of this document.
9    *
10   * 2. Redistributions in binary form must reproduce the
11   *    above copyright notice, this list of conditions and the
12   *    following disclaimer in the documentation and/or other
13   *    materials provided with the distribution.
14   *
15   * 3. The name "Exolab" must not be used to endorse or promote
16   *    products derived from this Software without prior written
17   *    permission of Intalio, Inc.  For written permission,
18   *    please contact info@exolab.org.
19   *
20   * 4. Products derived from this Software may not be called "Exolab"
21   *    nor may "Exolab" appear in their names without prior written
22   *    permission of Intalio, Inc. Exolab is a registered
23   *    trademark of Intalio, Inc.
24   *
25   * 5. Due credit should be given to the Exolab Project
26   *    (http://www.exolab.org/).
27   *
28   * THIS SOFTWARE IS PROVIDED BY INTALIO, INC. AND CONTRIBUTORS
29   * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
30   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
31   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
32   * INTALIO, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
33   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
35   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
37   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
39   * OF THE POSSIBILITY OF SUCH DAMAGE.
40   *
41   * Copyright 1999-2004 (C) Intalio Inc. All Rights Reserved.
42   *
43   * This file was originally developed by Keith Visco during the course
44   * of employment at Intalio Inc.
45   * Portions of this file developed by Keith Visco after Jan 19 2005 are
46   * Copyright (C) 2005 Keith Visco. All Rights Reserverd.
47   *
48   * $Id$
49   */
50  package org.exolab.castor.builder.factory;
51  
52  import java.util.ArrayList;
53  import java.util.Enumeration;
54  import java.util.List;
55  
56  import org.apache.commons.lang.StringUtils;
57  import org.exolab.castor.builder.BuilderConfiguration;
58  import org.exolab.castor.builder.ClassInfoResolver;
59  import org.exolab.castor.builder.GroupNaming;
60  import org.exolab.castor.builder.SGTypes;
61  import org.exolab.castor.builder.SourceGenerator;
62  import org.exolab.castor.builder.SourceGeneratorConstants;
63  import org.exolab.castor.builder.binding.XMLBindingComponent;
64  import org.exolab.castor.builder.info.ClassInfo;
65  import org.exolab.castor.builder.info.CollectionInfo;
66  import org.exolab.castor.builder.info.FieldInfo;
67  import org.exolab.castor.builder.info.XMLInfo;
68  import org.exolab.castor.builder.info.NodeType;
69  import org.exolab.castor.builder.info.nature.XMLInfoNature;
70  import org.exolab.castor.builder.types.XSList;
71  import org.exolab.castor.builder.types.XSListType;
72  import org.exolab.castor.builder.types.XSClass;
73  import org.exolab.castor.builder.types.XSString;
74  import org.exolab.castor.builder.types.XSType;
75  import org.exolab.castor.xml.schema.AttributeDecl;
76  import org.exolab.castor.xml.schema.ComplexType;
77  import org.exolab.castor.xml.schema.ElementDecl;
78  import org.exolab.castor.xml.schema.Facet;
79  import org.exolab.castor.xml.schema.Group;
80  import org.exolab.castor.xml.schema.Order;
81  import org.exolab.castor.xml.schema.Schema;
82  import org.exolab.castor.xml.schema.SchemaNames;
83  import org.exolab.castor.xml.schema.SimpleType;
84  import org.exolab.castor.xml.schema.Structure;
85  import org.exolab.castor.xml.schema.Wildcard;
86  import org.exolab.castor.xml.schema.XMLType;
87  import org.exolab.castor.xml.schema.simpletypes.ListType;
88  import org.exolab.javasource.JArrayType;
89  import org.exolab.javasource.JClass;
90  import org.exolab.javasource.JPrimitiveType;
91  import org.exolab.javasource.JType;
92  
93  /**
94   * The "Factory" responsible for creating fields for the given schema components.
95   *
96   * @author <a href="mailto:keith AT kvisco DOT com">Keith Visco</a>
97   * @version $Revision$ $Date: 2006-04-25 15:08:23 -0600 (Tue, 25 Apr 2006) $
98   */
99  public final class MemberFactory extends BaseFactory {
100 
101     /**
102      * Creates a new MemberFactory using the given FieldInfo factory.
103      *
104      * @param config the BuilderConfiguration
105      * @param infoFactory the FieldInfoFactory to use
106      * @param groupNaming Grou pnaming scheme to be used.
107      * @param sourceGenerator Calling source generator
108      */
109     public MemberFactory(final BuilderConfiguration config,
110             final FieldInfoFactory infoFactory,
111             final GroupNaming groupNaming,
112             final SourceGenerator sourceGenerator) {
113         super(config, infoFactory, groupNaming, sourceGenerator);
114 
115         if (getConfig().generateExtraCollectionMethods()) {
116             this.getInfoFactory().setCreateExtraMethods(true);
117         }
118         String suffix = getConfig().getProperty(CollectionInfo.REFERENCE_SUFFIX_PROPERTY, null);
119         this.getInfoFactory().setReferenceMethodSuffix(suffix);
120 
121         if (getConfig().boundPropertiesEnabled()) {
122             this.getInfoFactory().setBoundProperties(true);
123         }
124     } //-- MemberFactory
125 
126     /**
127      * Creates a FieldInfo for content models that support "any" element.
128      *
129      * @param any the wildcard we will operate on
130      * @param useJava50 if true then we will generate code for Java 5
131      *
132      * @return the new FieldInfo
133      */
134     public FieldInfo createFieldInfoForAny(final Wildcard any, final boolean useJava50) {
135         if (any == null) {
136             return null;
137         }
138 
139         //--currently anyAttribute is not supported
140         if (any.isAttributeWildcard()) {
141             return null;
142         }
143 
144         XSType xsType = new XSClass(SGTypes.OBJECT, "any");
145         String vName = "_anyObject";
146 //        if (getConfig().useOldFieldNaming()) {
147 //           StringUtils.leftPad(vName, 1, '_');
148 //        }
149         String xmlName   = null;
150         FieldInfo result = null;
151 
152         if (any.getMaxOccurs() > 1 || any.getMaxOccurs() < 0) {
153             result = this.getInfoFactory().createCollection(xsType, vName, "anyObject", getJavaNaming(), useJava50);
154             XSListType xsList = ((CollectionInfo) result).getXSList();
155             xsList.setMinimumSize(any.getMinOccurs());
156             xsList.setMaximumSize(any.getMaxOccurs());
157         } else {
158             result = this.getInfoFactory().createFieldInfo(xsType, vName);
159         }
160 
161         if (result.hasNature(XMLInfoNature.class.getName())) {
162             XMLInfoNature xmlNature = new XMLInfoNature(result);
163             
164             if (any.getMinOccurs() > 0) {
165                 xmlNature.setRequired(true);
166             } else {
167                 xmlNature.setRequired(false);
168             }
169             
170             xmlNature.setNodeName(xmlName);
171             
172             //--LIMITATION:
173             //-- 1- we currently support only the FIRST namespace
174             //-- 2- ##other, ##any are not supported
175             if (any.getNamespaces().hasMoreElements()) {
176                 String nsURI = (String) any.getNamespaces().nextElement();
177                 if (nsURI.length() > 0) {
178                     if (nsURI.equals("##targetNamespace")) {
179                         Schema schema = any.getSchema();
180                         if (schema != null) {
181                             xmlNature.setNamespaceURI(schema.getTargetNamespace());
182                         }
183                     } else if (!nsURI.startsWith("##")) {
184                         xmlNature.setNamespaceURI(nsURI);
185                     }
186                 }
187             } //--first namespace
188         }
189 
190         return result;
191     }
192 
193     /**
194      * Creates a FieldInfo to hold the value of a choice.
195      *
196      * @return the new FieldInfo
197      */
198     public FieldInfo createFieldInfoForChoiceValue() {
199         String fieldName = "_choiceValue";
200 //        if (getConfig().useOldFieldNaming()) {
201 //           StringUtils.leftPad(fieldName, 1, '_');
202 //        }
203         XSType xsType = new XSClass(SGTypes.OBJECT, "any");
204         FieldInfo fInfo = null;
205         fInfo = this.getInfoFactory().createFieldInfo(xsType, fieldName);
206         fInfo.setComment("Internal choice value storage");
207         fInfo.setTransient(true);
208         fInfo.setMethods(FieldInfo.READ_METHOD);
209         
210         if (fInfo.hasNature(XMLInfoNature.class.getName())) {
211             XMLInfoNature xmlNature = new XMLInfoNature(fInfo);
212             
213             xmlNature.setNodeType(NodeType.ELEMENT);
214             xmlNature.setRequired(false);
215             xmlNature.setNodeName("##any");
216         }
217         
218         return fInfo;
219     }
220 
221     /**
222      * Creates a FieldInfo for content.
223      * @param component {@link XMLBindingComponent} instance for accessing binding information.
224      * @param xsType the type of content
225      * @param useJava50 if true, code will be generated for Java 5
226      *
227      * @return the new FieldInfo
228      */
229     public FieldInfo createFieldInfoForContent(final XMLBindingComponent component, final XSType xsType, final boolean useJava50) {
230         String fieldName = "content";//new xsType()??? 
231         if (getConfig().useOldFieldNaming()) {
232            StringUtils.leftPad(fieldName, 1, '_');
233         }
234         if (component.getContentMemberName() != null) {
235             fieldName = component.getContentMemberName();
236         }
237         FieldInfo fInfo = null;
238         if (xsType.isCollection()) {
239             fInfo = this.getInfoFactory().createCollection(
240                     ((XSListType) xsType).getContentType(), fieldName, null, getJavaNaming(), useJava50);
241         } else {
242             fInfo = this.getInfoFactory().createFieldInfo(xsType, fieldName);
243         }
244         fInfo.setComment("internal content storage");
245         if (xsType instanceof XSString) {
246             fInfo.setDefaultValue("\"\"");
247         }
248         if (fInfo.hasNature(XMLInfoNature.class.getName())) {
249             XMLInfoNature xmlNature = new XMLInfoNature(fInfo);
250             xmlNature.setNodeType(NodeType.TEXT);
251             xmlNature.setRequired(false);
252             xmlNature.setNodeName("#text");
253         }
254         return fInfo;
255     }
256 
257     /**
258      * Creates a FieldInfo object for the given XMLBindingComponent.
259      *
260      * @param component the XMLBindingComponent to create the FieldInfo for
261      * @param resolver resolver to use to find ClassInfo
262      * @param useJava50 if true, code will be generated for Java 5
263      * @return the FieldInfo for the given attribute declaration
264      */
265     public FieldInfo createFieldInfo(final XMLBindingComponent component,
266             final ClassInfoResolver resolver, final boolean useJava50) {
267         String xmlName = component.getXMLName();
268         String memberName = component.getJavaMemberName();
269         if (getConfig().useOldFieldNaming()) {
270            if (!memberName.startsWith("_")) {
271               memberName = "_" + memberName;
272            }
273         }
274 
275         XMLType xmlType = component.getXMLType();
276 
277         ClassInfo classInfo = resolver.resolve(component);
278 
279         XSType   xsType = null;
280         FieldInfo fieldInfo = null;
281         boolean enumeration = false;
282         boolean simpleTypeCollection = false;
283 
284         if (xmlType != null) {
285             if (xmlType.isSimpleType() ) {
286                 SimpleType simpleType = (SimpleType) xmlType;
287 
288                 SimpleType baseType = null;
289                 String derivationMethod = simpleType.getDerivationMethod();
290                 if (derivationMethod != null) {
291                     if (SchemaNames.RESTRICTION.equals(derivationMethod)) {
292                         baseType = (SimpleType) simpleType.getBaseType();
293                     }
294                 }
295 
296                 //-- handle special case for enumerated types
297                 if (simpleType.hasFacet(Facet.ENUMERATION)) {
298                     //-- LOok FoR CLasSiNfO iF ReSoLvR is NoT NuLL
299                     enumeration = true;
300                     if (resolver != null) {
301                         classInfo = resolver.resolve(xmlType);
302                     }
303                     if (classInfo != null) {
304                         XMLInfoNature xmlNature = new XMLInfoNature(classInfo);
305                         xsType = xmlNature.getSchemaType();
306                     }
307                 } else if ((simpleType instanceof ListType) || (baseType instanceof ListType)) {
308                     if (baseType != null) {
309                         if (!baseType.isBuiltInType()) {
310                             simpleTypeCollection = true;
311                         }
312                     } else {
313                         if (!simpleType.isBuiltInType()) {
314                             simpleTypeCollection = true;
315                         }
316                     }
317                     
318                     // handle special case where the list type uses an item type
319                     // that has enumeration facets defined.
320                     ListType listType = (ListType) simpleType;
321                     if (listType == null) {
322                         listType = (ListType) baseType;
323                     }
324                     SimpleType itemType = listType.getItemType();
325                     if (itemType.hasFacet(Facet.ENUMERATION)) {
326                         ClassInfo itemClassInfo = resolver.resolve(itemType);
327                         if (itemClassInfo != null) {
328                             xsType = new XMLInfoNature(itemClassInfo).getSchemaType();
329                         } else {
330                             XMLBindingComponent temp = new XMLBindingComponent(
331                                     getConfig(), getGroupNaming());
332                             temp.setBinding(component.getBinding());
333                             temp.setView(itemType);
334                             String packageName = temp.getJavaPackage();
335                             if (packageName != null && packageName.length() > 0) {
336                                 packageName = packageName + "." + SourceGeneratorConstants.TYPES_PACKAGE;
337                             } else {
338                                 packageName = SourceGeneratorConstants.TYPES_PACKAGE;
339                             }
340                             JClass tempClass = new JClass(packageName+ "." + temp.getJavaClassName(), getConfig().useOldFieldNaming());
341                             xsType = new XSClass(tempClass);
342                             xsType.setAsEnumerated(true);
343                         }
344                     }
345                     
346                     
347                 }
348 
349                 if (xsType == null) {
350                     xsType = component.getJavaType();
351                 }
352             } else if (xmlType.isAnyType()) {
353                 //-- Just treat as java.lang.Object.
354                 if (classInfo != null) {
355                     XMLInfoNature xmlNature = new XMLInfoNature(classInfo);
356                     xsType = xmlNature.getSchemaType();
357                 }
358                 if (xsType == null) {
359                     xsType = new XSClass(SGTypes.OBJECT);
360                 }
361             } else if (xmlType.isComplexType() && (xmlType.getName() != null)) {
362                 //--if we use the type method then no class is output for
363                 //--the element we are processing
364                 if (getConfig().mappingSchemaType2Java()) {
365                     XMLBindingComponent temp = new XMLBindingComponent(
366                             getConfig(), getGroupNaming());
367                     temp.setBinding(component.getBinding());
368                     temp.setView(xmlType);
369                     ClassInfo typeInfo = resolver.resolve(xmlType);
370                     if (typeInfo != null) {
371                         // if we have not processed the <complexType> referenced
372                         // by the ClassInfo yet, this will return null
373                         // TODO find a way to resolve an unprocessed <complexType>
374                         XMLInfoNature xmlNature = new XMLInfoNature(typeInfo);
375                         xsType = xmlNature.getSchemaType();
376                     } else {
377                         String className = temp.getQualifiedName();
378                         if (className != null) {
379                             JClass jClass = new JClass(className,getConfig().useOldFieldNaming());
380                             if (((ComplexType) xmlType).isAbstract()) {
381                                 jClass.getModifiers().setAbstract(true);
382                             }
383                             xsType = new XSClass(jClass);
384                             className = null;
385                         }
386                     }
387                 }
388             } // complexType
389         } else {
390             if (xsType == null) {
391                 xsType = component.getJavaType();
392             }
393 
394             if (xsType == null) {
395                 //-- patch for bug 1471 (No XMLType specified)
396                 //-- treat unspecified type as anyType
397                 switch (component.getAnnotated().getStructureType()) {
398                 case Structure.ATTRIBUTE:
399                     AttributeDecl attribute = (AttributeDecl) component.getAnnotated();
400                     if (!attribute.hasXMLType()) {
401                         xsType = new XSClass(SGTypes.OBJECT);
402                     } 
403                     break;                
404                 case Structure.ELEMENT:
405                     ElementDecl element = (ElementDecl) component.getAnnotated();
406                     if (!element.hasXMLType()) {
407                         xsType = new XSClass(SGTypes.OBJECT);
408                     } 
409                     break;
410                 default:
411                     // probably a model-group
412                     break;
413                 }
414             }
415         }
416 
417         // is the XSType found?
418         if (xsType == null) {
419             String className = component.getQualifiedName();
420             JClass jClass = new JClass(className, getConfig().useOldFieldNaming());
421             if (component.isAbstract()) {
422                 jClass.getModifiers().setAbstract(true);
423             }
424             if (getConfig().isAutomaticConflictResolution()) {
425                 getSourceGenerator().getXMLInfoRegistry().bind(jClass, 
426                         component, "field");
427             }
428             xsType = new XSClass(jClass);
429             if (xmlType != null && xmlType.isComplexType()) {
430                 ComplexType complexType = (ComplexType) xmlType;
431                 if (complexType.isAbstract() || getConfig().mappingSchemaElement2Java()) {
432                     jClass.getModifiers().setAbstract(true);
433                 }
434             }
435             className = null;
436         }
437 
438         // create the fieldInfo
439         // check whether this should be a collection or not
440         int maxOccurs = component.getUpperBound();
441         int minOccurs = component.getLowerBound();
442         if (simpleTypeCollection
443                 || ((maxOccurs < 0 || maxOccurs > 1) && !this.isChoice(component))) {
444             String vName = memberName + "List";
445 
446             // if xmlName is null it means that
447             // we are processing a container object (group)
448             // so we need to adjust the name of the members of the collection
449             CollectionInfo cInfo;
450             cInfo = this.getInfoFactory().createCollection(xsType, vName, memberName,
451                                                        component.getCollectionType(), getJavaNaming(), useJava50);
452 
453             XSListType xsList = cInfo.getXSList();
454             if (!simpleTypeCollection) {
455                 xsList.setMaximumSize(maxOccurs);
456                 xsList.setMinimumSize(minOccurs);
457             } else {
458                 if (xsList instanceof XSList) {
459                     ((XSList) xsList).setDerivedFromXSList(true);
460                 }
461             }
462             fieldInfo = cInfo;
463         } else  {
464             switch (xsType.getType()) {
465                 case XSType.ID_TYPE:
466                      fieldInfo = this.getInfoFactory().createIdentity(memberName);
467                      break;
468                 case XSType.COLLECTION:
469                 case XSType.IDREFS_TYPE:
470                 case XSType.NMTOKENS_TYPE:
471                     String collectionName = component.getCollectionType();
472                     XSType contentType = ((XSListType) xsType).getContentType();
473                     fieldInfo = this.getInfoFactory().createCollection(contentType,
474                                                                    memberName, memberName,
475                                                                    collectionName, getJavaNaming(), useJava50);
476                     break;
477                 default:
478                     fieldInfo = this.getInfoFactory().createFieldInfo(xsType, memberName);
479                     break;
480             }
481         }
482 
483         // initialize the field
484         XMLInfoNature xmlNature = new XMLInfoNature(fieldInfo);
485         xmlNature.setNodeName(xmlName);
486         xmlNature.setRequired(minOccurs > 0);
487         switch (component.getAnnotated().getStructureType()) {
488             case Structure.ELEMENT:
489                 xmlNature.setNodeType(NodeType.ELEMENT);
490                  break;
491             case Structure.ATTRIBUTE:
492                 xmlNature.setNodeType(NodeType.ATTRIBUTE);
493                 break;
494             case Structure.MODELGROUP:
495             case Structure.GROUP:
496                 xmlNature.setNodeName(XMLInfo.CHOICE_NODE_NAME_ERROR_INDICATION);
497                 fieldInfo.setContainer(true);
498                 break;
499             default:
500                 break;
501         }
502 
503         //-- handle namespace URI / prefix
504         String nsURI = component.getTargetNamespace();
505         if ((nsURI != null) && (nsURI.length() > 0)) {
506             xmlNature.setNamespaceURI(nsURI);
507             // TODO set the prefix used in the XML Schema
508             //      in order to use it inside the Marshaling Framework
509         }
510 
511         // handle default value (if any is set)
512         handleDefaultValue(component, classInfo, xsType, fieldInfo, enumeration);
513 
514         //-- handle nillable values
515         if (component.isNillable()) {
516             fieldInfo.setNillable(true);
517         }
518 
519         //-- add annotated comments
520         String comment = createComment(component.getAnnotated());
521         if (comment != null) {
522              fieldInfo.setComment(comment);
523         }
524 
525         //--specific field handler or validator?
526         if (component.getXMLFieldHandler() != null) {
527             fieldInfo.setXMLFieldHandler(component.getXMLFieldHandler());
528         }
529 
530         if (component.getValidator() != null) {
531             fieldInfo.setValidator(component.getValidator());
532         }
533 
534         if (component.getVisiblity() != null) {
535             String visibility = component.getVisiblity();
536             fieldInfo.setVisibility(visibility);
537         }
538         
539         // deal with substitution groups
540         switch (component.getAnnotated().getStructureType()) {
541         case Structure.ELEMENT:
542             ElementDecl elementDeclaration = (ElementDecl) component.getAnnotated();
543             if (elementDeclaration.isReference()) {
544                 elementDeclaration = elementDeclaration.getReference();
545             }
546             Enumeration<ElementDecl> possibleSubstitutes = elementDeclaration.getSubstitutionGroupMembers(); 
547             if (possibleSubstitutes.hasMoreElements()) {
548                 List<String> substitutionGroupMembers = new ArrayList<String>();
549                 while (possibleSubstitutes.hasMoreElements()) {
550                     ElementDecl substitute = possibleSubstitutes.nextElement();
551                     substitutionGroupMembers.add(substitute.getName());
552                 }
553                 fieldInfo.setSubstitutionGroupMembers(substitutionGroupMembers);
554             }
555         default:
556         }
557 
558         return fieldInfo;
559     }
560 
561     /**
562      * Determines if the given <code>component</code> represents a choice.
563      * 
564      * @param component
565      *            The XMLBindingComponent to check.
566      * @return <code>true</code> if and only if the given XMLBindingComponent
567      *         represents a choice. Otherwise returns <code>false</code>
568      */
569     private boolean isChoice(final XMLBindingComponent component) {
570         Group group = this.getGroup(component.getAnnotated());
571         if (group == null || group.getOrder() == null) {
572             return false;
573         }
574         
575         return group.getOrder() == Order.choice;
576     }
577 
578     /**
579      * Returns the given <code>structure</code> as Group if it represents one.<br>
580      * <br>
581      * If the given <code>structure</code> has the structure type
582      * <code>GROUP</code> this method returns the given <code>structure</code>
583      * itself (casted to Group). If the structure is of any other type or is
584      * <code>null</code> this method will return <code>null</code>
585      * 
586      * @param structure
587      *            The Structure to be returned as Group.
588      * @return The given <code>structure</code> if and only if it is a group;
589      *         otherwise returns <code>null</code>.
590      */
591     private Group getGroup(final Structure structure) {
592         if (structure == null) {
593             return null;
594         }
595         
596         if (structure.getStructureType() == Structure.GROUP) {
597             return (Group) structure;
598         }
599         
600         return null;
601     }
602 
603     /**
604      * Handle default or fixed value, if any is set.
605      * @param component The component on which a default value is set
606      * @param classInfo The corresponding ClassInfo instance.
607      * @param xsType The schema type of the component.
608      * @param fieldInfo The FieldInfo into which to inject a default value
609      * @param enumeration If we are looking at an enumeration.
610      */
611     private void handleDefaultValue(final XMLBindingComponent component, final ClassInfo classInfo,
612             final XSType xsType, final FieldInfo fieldInfo, final boolean enumeration) {
613 
614         String value = component.getValue();
615         if (value == null) {
616             return;
617         }
618 
619         value = adjustDefaultValue(xsType, value);
620 
621         if (value.length() == 0) {
622             value = "\"\"";
623         }
624 
625         // TODO Need to change this...and to validate the value...to be done at reading time.
626 
627         //-- clean up value
628         //-- if the xsd field is mapped into a java.lang.String
629         if  (xsType.getJType().toString().equals("java.lang.String")) {
630             char ch = value.charAt(0);
631             if (ch != '\'' && ch != '\"') {
632                 value = '\"' + value + '\"';
633             }
634             // deals with special characters, e.g. line feed
635             StringBuffer buffer = new StringBuffer(value.length());
636             for (int i = 0; i < value.length(); i++) {
637                 char character = value.charAt(i);
638                 switch(character) {
639                 case '\n': 
640                     buffer.append("\\n");
641                     break;
642                 default:
643                     buffer.append(character);
644                 }
645             }
646             value = buffer.toString();
647         } else if (enumeration) {
648             JType jType = (classInfo != null) ? classInfo.getJClass() : xsType.getJType();
649             if (getSourceGenerator().useJava5Enums()) {
650                 value = jType.getName() + ".fromValue(\"" + value + "\")";
651             } else {
652                 value = jType.getName() + ".valueOf(\"" + value + "\")";    
653             }
654         } else if (xsType.getJType().isArray()) {
655             JType componentType = ((JArrayType) xsType.getJType()).getComponentType();
656             if (componentType.isPrimitive()) {
657                 JPrimitiveType primitive = (JPrimitiveType) componentType;
658                 value = "new " + primitive.getName() + "[] { "
659                       + primitive.getWrapperName() + ".valueOf(\"" + value
660                       + "\")." + primitive.getName() + "Value() }";
661             } else {
662                 value = "new " + componentType.getName() + "[] { "
663                       + componentType.getName() + ".valueOf(\"" + value + "\") }";
664                 
665             }
666         } else if (!(xsType.getJType().isPrimitive())) {
667             if (xsType.isDateTime()) {
668                 // Castor marshals DATETIME_TYPE into java.util.Date(), so we need to convert it
669                 if (xsType.getType() == XSType.DATETIME_TYPE) {
670                     // FIXME This fails if the DateTIme has a time zone
671                     //       because we throw away the time zone in toDate()
672                     value = "new org.exolab.castor.types.DateTime(\"" + value + "\").toDate()";
673                 } else {
674                     value = "new " + xsType.getJType().getName() + "(\"" + value + "\")";
675                 }
676             } else {
677                 // FIXME This works only if a constructor with String as parameter exists
678                 value = "new " + xsType.getJType().getName() + "(\"" + value + "\")";
679             }
680         }
681 
682         if (component.isFixed()) {
683             fieldInfo.setFixedValue(value);
684         } else {
685             fieldInfo.setDefaultValue(value);
686         }
687     }
688 
689     /**
690      * Adjusts the default value string represenation to reflect the semantics
691      * of various 'special' data types.
692      *
693      * @param xsType The XMl schems type of the value to adjust
694      * @param value The actual value to adjust
695      * @return an adjusted default value.
696      */
697     private String adjustDefaultValue(final XSType xsType, final String value) {
698         switch (xsType.getType()) {
699             case XSType.FLOAT_TYPE:
700                 return value + 'f';
701             case XSType.BOOLEAN_TYPE:
702                 Boolean bool = new Boolean(value);
703                 return bool.toString();
704             default:
705                 break;
706         }
707         return value;
708     }
709 
710 } //-- MemberFactory