Save This Page
Home » axis2-1.5-src » org.apache » axis2 » schema » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements. See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership. The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License. You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied. See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   package org.apache.axis2.schema;
   21   
   22   import org.apache.axis2.namespace.Constants;
   23   import org.apache.axis2.schema.i18n.SchemaCompilerMessages;
   24   import org.apache.axis2.schema.util.PrimitiveTypeFinder;
   25   import org.apache.axis2.schema.util.PrimitiveTypeWrapper;
   26   import org.apache.axis2.schema.util.SchemaPropertyLoader;
   27   import org.apache.axis2.schema.writer.BeanWriter;
   28   import org.apache.axis2.util.SchemaUtil;
   29   import org.apache.axis2.util.URLProcessor;
   30   import org.apache.commons.logging.Log;
   31   import org.apache.commons.logging.LogFactory;
   32   import org.apache.ws.commons.schema.XmlSchema;
   33   import org.apache.ws.commons.schema.XmlSchemaAll;
   34   import org.apache.ws.commons.schema.XmlSchemaAny;
   35   import org.apache.ws.commons.schema.XmlSchemaAnyAttribute;
   36   import org.apache.ws.commons.schema.XmlSchemaAttribute;
   37   import org.apache.ws.commons.schema.XmlSchemaAttributeGroup;
   38   import org.apache.ws.commons.schema.XmlSchemaAttributeGroupRef;
   39   import org.apache.ws.commons.schema.XmlSchemaChoice;
   40   import org.apache.ws.commons.schema.XmlSchemaComplexContent;
   41   import org.apache.ws.commons.schema.XmlSchemaComplexContentExtension;
   42   import org.apache.ws.commons.schema.XmlSchemaComplexContentRestriction;
   43   import org.apache.ws.commons.schema.XmlSchemaComplexType;
   44   import org.apache.ws.commons.schema.XmlSchemaContent;
   45   import org.apache.ws.commons.schema.XmlSchemaContentModel;
   46   import org.apache.ws.commons.schema.XmlSchemaElement;
   47   import org.apache.ws.commons.schema.XmlSchemaEnumerationFacet;
   48   import org.apache.ws.commons.schema.XmlSchemaExternal;
   49   import org.apache.ws.commons.schema.XmlSchemaGroup;
   50   import org.apache.ws.commons.schema.XmlSchemaGroupBase;
   51   import org.apache.ws.commons.schema.XmlSchemaGroupRef;
   52   import org.apache.ws.commons.schema.XmlSchemaImport;
   53   import org.apache.ws.commons.schema.XmlSchemaInclude;
   54   import org.apache.ws.commons.schema.XmlSchemaLengthFacet;
   55   import org.apache.ws.commons.schema.XmlSchemaMaxExclusiveFacet;
   56   import org.apache.ws.commons.schema.XmlSchemaMaxInclusiveFacet;
   57   import org.apache.ws.commons.schema.XmlSchemaMaxLengthFacet;
   58   import org.apache.ws.commons.schema.XmlSchemaMinExclusiveFacet;
   59   import org.apache.ws.commons.schema.XmlSchemaMinInclusiveFacet;
   60   import org.apache.ws.commons.schema.XmlSchemaMinLengthFacet;
   61   import org.apache.ws.commons.schema.XmlSchemaObject;
   62   import org.apache.ws.commons.schema.XmlSchemaObjectCollection;
   63   import org.apache.ws.commons.schema.XmlSchemaObjectTable;
   64   import org.apache.ws.commons.schema.XmlSchemaParticle;
   65   import org.apache.ws.commons.schema.XmlSchemaPatternFacet;
   66   import org.apache.ws.commons.schema.XmlSchemaSequence;
   67   import org.apache.ws.commons.schema.XmlSchemaSimpleContent;
   68   import org.apache.ws.commons.schema.XmlSchemaSimpleContentExtension;
   69   import org.apache.ws.commons.schema.XmlSchemaSimpleContentRestriction;
   70   import org.apache.ws.commons.schema.XmlSchemaSimpleType;
   71   import org.apache.ws.commons.schema.XmlSchemaSimpleTypeContent;
   72   import org.apache.ws.commons.schema.XmlSchemaSimpleTypeList;
   73   import org.apache.ws.commons.schema.XmlSchemaSimpleTypeRestriction;
   74   import org.apache.ws.commons.schema.XmlSchemaSimpleTypeUnion;
   75   import org.apache.ws.commons.schema.XmlSchemaType;
   76   
   77   import javax.xml.namespace.QName;
   78   import java.util.ArrayList;
   79   import java.util.HashMap;
   80   import java.util.HashSet;
   81   import java.util.Iterator;
   82   import java.util.LinkedHashMap;
   83   import java.util.List;
   84   import java.util.Map;
   85   import java.util.Properties;
   86   
   87   /**
   88    * Schema compiler for ADB. Based on WS-Commons schema object model.
   89    */
   90   public class SchemaCompiler {
   91   
   92       public static final int COMPONENT_TYPE = 1;
   93       public static final int COMPONENT_ELEMENT = 2;
   94       public static final int COMPONENT_ATTRIBUTE = 3;
   95       public static final int COMPONENT_ATTRIBUTE_GROUP = 4;
   96       public static final int COMPONENT_GROUP = 5;
   97   
   98   
   99       private static final Log log = LogFactory.getLog(SchemaCompiler.class);
  100   
  101       private CompilerOptions options;
  102       private HashMap processedTypemap;
  103       // have to keep a seperate group type map since same
  104       // name can be used to group and complextype
  105       private HashMap processedGroupTypeMap;
  106   
  107       //the list of processedElements for the outer elements
  108       private HashMap processedElementMap;
  109   
  110       private HashMap processedAnonymousComplexTypesMap;
  111   
  112       //we need this map to keep the referenced elements. these elements need to be kept seperate
  113       //to avoid conflicts
  114       private HashMap processedElementRefMap;
  115       private HashMap simpleTypesMap;
  116       private HashMap changedTypeMap;
  117   
  118       private HashSet changedSimpleTypeSet;
  119       private HashSet changedComplexTypeSet;
  120       private HashSet changedElementSet;
  121   
  122       // this map is necessary to retain the metainformation of types. The reason why these
  123       // meta info 'bags' would be useful later is to cater for the extensions and restrictions
  124       // of types
  125       private HashMap processedTypeMetaInfoMap;
  126   
  127       //
  128       private ArrayList processedElementList;
  129   
  130       //a list of nillable elements - used to generate code
  131       //for nillable elements
  132       private List nillableElementList;
  133       // writee reference
  134       private BeanWriter writer = null;
  135       private Map baseSchemaTypeMap = null;
  136   
  137       //a map for keeping the already loaded schemas
  138       //the key is the targetnamespace and the value is the schema object
  139       private Map loadedSchemaMap = new HashMap();
  140   
  141       // A map keeping the available schemas
  142       //the key is the targetnamespace and the value is the schema object
  143       //this map will be populated when multiple schemas
  144       //are fed to the schema compiler!
  145       private Map availableSchemaMap = new HashMap();
  146   
  147       private Map loadedSourceURI = new HashMap();
  148   
  149       // a list of externally identified QNames to be processed. This becomes
  150       // useful when  only a list of external elements need to be processed
  151   
  152       public static final String ANY_ELEMENT_FIELD_NAME = "extraElement";
  153       public static final String EXTRA_ATTRIBUTE_FIELD_NAME = "extraAttributes";
  154   
  155       public static final String USE_OPTIONAL = "optional";
  156       public static final String USE_REQUIRED = "required";
  157       public static final String USE_NONE = "none";
  158   
  159       /**
  160        * @return the processes element map
  161        *         includes the Qname of the element as the key and a
  162        *         String representing the fully qualified class name
  163        */
  164       public HashMap getProcessedElementMap() {
  165           return processedElementMap;
  166       }
  167   
  168   
  169       /**
  170        * @return a map of Qname vs models. A model can be anything,
  171        *         ranging from a DOM document to a stream. This is taken from the
  172        *         writer and the schema compiler has no control over it
  173        */
  174       public Map getProcessedModelMap() {
  175           return writer.getModelMap();
  176       }
  177   
  178       /**
  179        * Constructor - Accepts a options bean
  180        *
  181        * @param options
  182        */
  183       public SchemaCompiler(CompilerOptions options) throws SchemaCompilationException {
  184   
  185           if (options == null) {
  186               //create an empty options object
  187               this.options = new CompilerOptions();
  188           } else {
  189               this.options = options;
  190           }
  191   
  192           //instantiate the maps
  193           processedTypemap = new HashMap();
  194           processedGroupTypeMap = new HashMap();
  195   
  196           processedElementMap = new HashMap();
  197           simpleTypesMap = new HashMap();
  198           processedElementList = new ArrayList();
  199           processedAnonymousComplexTypesMap = new HashMap();
  200           changedTypeMap = new HashMap();
  201           processedTypeMetaInfoMap = new HashMap();
  202           processedElementRefMap = new HashMap();
  203           nillableElementList = new ArrayList();
  204   
  205           changedComplexTypeSet = new HashSet();
  206           changedSimpleTypeSet = new HashSet();
  207           changedElementSet = new HashSet();
  208   
  209           //load the writer and initiliaze the base types
  210           writer = SchemaPropertyLoader.getBeanWriterInstance();
  211           writer.init(this.options);
  212   
  213           //load the base types
  214           baseSchemaTypeMap = SchemaPropertyLoader.getTypeMapperInstance().getTypeMap();
  215           // adding all the soap encoding schema classes
  216           processedTypemap.putAll(SchemaPropertyLoader.getTypeMapperInstance().getSoapEncodingTypesMap());
  217   
  218   
  219       }
  220   
  221       /**
  222        * Compile a list of schemas
  223        * This actually calls the compile (XmlSchema s) method repeatedly
  224        *
  225        * @param schemalist
  226        * @throws SchemaCompilationException
  227        * @see #compile(org.apache.ws.commons.schema.XmlSchema)
  228        */
  229       public void compile(List schemalist) throws SchemaCompilationException {
  230           try {
  231   
  232               if (schemalist.isEmpty()) {
  233                   return;
  234               }
  235   
  236               //clear the loaded and available maps
  237               loadedSchemaMap.clear();
  238               availableSchemaMap.clear();
  239   
  240               XmlSchema schema;
  241               // first round - populate the avaialble map
  242               for (int i = 0; i < schemalist.size(); i++) {
  243                   schema = (XmlSchema) schemalist.get(i);
  244                   availableSchemaMap.put(
  245                           schema.getTargetNamespace(),
  246                           schema);
  247               }
  248   
  249               //set a mapper package if not avaialable
  250               if (writer.getExtensionMapperPackageName() == null) {
  251                   String nsp = null;
  252                   //get the first schema from the list and take that namespace as the
  253                   //mapper namespace
  254                   for (int i = 0; nsp == null && i < schemalist.size(); i++) {
  255                       nsp = ((XmlSchema) schemalist.get(i)).getTargetNamespace();
  256                       if ((nsp != null) && !nsp.equals("")){
  257                           break;
  258                       }
  259                       XmlSchema[] schemas = SchemaUtil.getAllSchemas((XmlSchema) schemalist.get(i));
  260                       for (int j = 0; schemas != null && j < schemas.length; j++) {
  261                           nsp = schemas[j].getTargetNamespace();
  262                           if (nsp != null)
  263                               break;
  264                       }
  265                   }
  266                   if (nsp == null) {
  267                       nsp = URLProcessor.DEFAULT_PACKAGE;
  268                   }
  269   
  270                   // if this name space exists in the ns2p list then we use it.
  271                   if ((options.getNs2PackageMap() != null)
  272                           && (options.getNs2PackageMap().containsKey(nsp))) {
  273                       writer.registerExtensionMapperPackageName((String) options.getNs2PackageMap().get(nsp));
  274                   } else {
  275                       writer.registerExtensionMapperPackageName(URLProcessor.makePackageName(nsp));
  276                   }
  277               }
  278               // second round - call the schema compiler one by one
  279               for (int i = 0; i < schemalist.size(); i++) {
  280                   compile((XmlSchema) schemalist.get(i), true);
  281               }
  282   
  283               //finish up
  284               finalizeSchemaCompilation();
  285   
  286           } catch (SchemaCompilationException e) {
  287               throw e;
  288           } catch (Exception e) {
  289               throw new SchemaCompilationException(e);
  290           }
  291       }
  292   
  293       /**
  294        * Compile (rather codegen) a single schema element
  295        *
  296        * @param schema
  297        * @throws SchemaCompilationException
  298        */
  299       public void compile(XmlSchema schema) throws SchemaCompilationException {
  300           compile(schema, false);
  301       }
  302   
  303       /**
  304        * Compile (rather codegen) a single schema element
  305        *
  306        * @param schema
  307        * @param isPartofGroup
  308        * @throws SchemaCompilationException
  309        */
  310       private void compile(XmlSchema schema, boolean isPartofGroup) throws SchemaCompilationException {
  311   
  312           // some documents explicitly imports the schema of built in types. We don't actually need to compile
  313           // the built-in types. So check the target namespace here and ignore it.
  314           if (Constants.URI_2001_SCHEMA_XSD.equals(schema.getTargetNamespace())) {
  315               return;
  316           }
  317   
  318           //register the package from this namespace as the mapper classes package
  319           if (!isPartofGroup) {
  320               //set a mapper package if not avaialable
  321               if (writer.getExtensionMapperPackageName() == null) {
  322                   writer.registerExtensionMapperPackageName(
  323                           URLProcessor.makePackageName(schema.getTargetNamespace()));
  324               }
  325           }
  326   
  327           //First look for the schemas that are imported and process them
  328           //Note that these are processed recursively!
  329   
  330           //add the schema to the loaded schema list
  331           if (!loadedSchemaMap.containsKey(schema.getTargetNamespace())) {
  332               loadedSchemaMap.put(schema.getTargetNamespace(), schema);
  333           }
  334   
  335           // If we have/are loading a schema with a specific targetnamespace from a certain URI,
  336           // then just return back to the caller to avoid recursion.
  337           if (schema.getSourceURI() != null) {
  338               String key = schema.getTargetNamespace() + ":" + schema.getSourceURI();
  339               if (loadedSourceURI.containsKey(key)) {
  340                   return;
  341               }
  342               loadedSourceURI.put(key, key);
  343           }
  344   
  345           XmlSchemaObjectCollection includes = schema.getIncludes();
  346           if (includes != null) {
  347               Iterator tempIterator = includes.getIterator();
  348               while (tempIterator.hasNext()) {
  349                   Object o = tempIterator.next();
  350                   if (o instanceof XmlSchemaImport) {
  351                       XmlSchema schema1 = ((XmlSchemaImport) o).getSchema();
  352                       if (schema1 != null) compile(schema1, isPartofGroup);
  353                   }
  354                   if (o instanceof XmlSchemaInclude) {
  355                       XmlSchema schema1 = ((XmlSchemaInclude) o).getSchema();
  356                       if (schema1 != null) compile(schema1, isPartofGroup);
  357                   }
  358               }
  359           }
  360   
  361           //select all the elements. We generate the code for types
  362           //only if the elements refer them!!! regardless of the fact that
  363           //we have a list of elementnames, we'll need to process all the elements
  364           XmlSchemaObjectTable elements = schema.getElements();
  365           Iterator xmlSchemaElement1Iterator = elements.getValues();
  366           while (xmlSchemaElement1Iterator.hasNext()) {
  367               //this is the set of outer elements so we need to generate classes
  368               //The outermost elements do not contain occurence counts (!) so we do not need
  369               //to check for arraytypes
  370               processElement((XmlSchemaElement) xmlSchemaElement1Iterator.next(), schema);
  371           }
  372   
  373           Iterator xmlSchemaElement2Iterator = elements.getValues();
  374   
  375           // re-iterate through the elements and write them one by one
  376           // if the mode is unpack this process will not really write the
  377           // classes but will accumilate the models for a final single shot
  378           // write
  379           while (xmlSchemaElement2Iterator.hasNext()) {
  380               //this is the set of outer elements so we need to generate classes
  381               writeElement((XmlSchemaElement) xmlSchemaElement2Iterator.next());
  382           }
  383   
  384           if (options.isGenerateAll()) {
  385               Iterator xmlSchemaTypes2Iterator = schema.getSchemaTypes().getValues();
  386               while (xmlSchemaTypes2Iterator.hasNext()) {
  387                   XmlSchemaType schemaType = (XmlSchemaType) xmlSchemaTypes2Iterator.next();
  388                   if (this.isAlreadyProcessed(schemaType.getQName())) {
  389                       continue;
  390                   }
  391                   if (schemaType instanceof XmlSchemaComplexType) {
  392                       //write classes for complex types
  393                       XmlSchemaComplexType complexType = (XmlSchemaComplexType) schemaType;
  394                       if (complexType.getName() != null) {
  395                           processNamedComplexSchemaType(complexType, schema);
  396                       }
  397                   } else if (schemaType instanceof XmlSchemaSimpleType) {
  398                       //process simple type
  399                       processSimpleSchemaType((XmlSchemaSimpleType) schemaType,
  400                               null,
  401                               schema, null);
  402                   }
  403               }
  404           }
  405   
  406           if (!isPartofGroup) {
  407               //complete the compilation
  408               finalizeSchemaCompilation();
  409           }
  410       }
  411   
  412       /**
  413        * Completes the schema compilation process by writing the
  414        * mappers and the classes in a batch if needed
  415        *
  416        * @throws SchemaCompilationException
  417        */
  418       private void finalizeSchemaCompilation() throws SchemaCompilationException {
  419           //write the extension mapping class
  420           writer.writeExtensionMapper(
  421                   (BeanWriterMetaInfoHolder[])
  422                           processedTypeMetaInfoMap.values().toArray(
  423                                   new BeanWriterMetaInfoHolder[processedTypeMetaInfoMap.size()]));
  424   
  425   
  426           if (options.isWrapClasses()) {
  427               writer.writeBatch();
  428           }
  429   
  430           // resets the changed types
  431           XmlSchemaComplexType xmlSchemaComplexType = null;
  432           for (Iterator iter = changedComplexTypeSet.iterator();iter.hasNext();){
  433               xmlSchemaComplexType = (XmlSchemaComplexType) iter.next();
  434               xmlSchemaComplexType.setName(null);
  435           }
  436   
  437           XmlSchemaSimpleType xmlSchemaSimpleType = null;
  438           for (Iterator iter = changedSimpleTypeSet.iterator();iter.hasNext();){
  439               xmlSchemaSimpleType = (XmlSchemaSimpleType) iter.next();
  440               xmlSchemaSimpleType.setName(null);
  441           }
  442   
  443           XmlSchemaElement xmlSchemaElement = null;
  444           for (Iterator iter = changedElementSet.iterator();iter.hasNext();){
  445               xmlSchemaElement = (XmlSchemaElement) iter.next();
  446               xmlSchemaElement.setSchemaTypeName(null);
  447           }
  448   
  449       }
  450   
  451       /**
  452        * @return the property map of the schemacompiler.
  453        *         In this case it would be the property map loaded from
  454        *         the configuration file
  455        */
  456       public Properties getCompilerProperties() {
  457           return SchemaPropertyLoader.getPropertyMap();
  458       }
  459   
  460   
  461       /**
  462        * Writes the element
  463        *
  464        * @param xsElt
  465        * @throws SchemaCompilationException
  466        */
  467       private void writeElement(XmlSchemaElement xsElt) throws SchemaCompilationException {
  468   
  469           if (this.processedElementMap.containsKey(xsElt.getQName())) {
  470               return;
  471           }
  472   
  473           XmlSchemaType schemaType = xsElt.getSchemaType();
  474   
  475           BeanWriterMetaInfoHolder metainf = new BeanWriterMetaInfoHolder();
  476           if (schemaType != null && schemaType.getName() != null) {
  477               //this is a named type
  478               QName qName = schemaType.getQName();
  479               //find the class name
  480               String className = findClassName(qName, isArray(xsElt));
  481   
  482               //this means the schema type actually returns a different QName
  483               if (changedTypeMap.containsKey(qName)) {
  484                   metainf.registerMapping(xsElt.getQName(),
  485                           (QName) changedTypeMap.get(qName),
  486                           className);
  487               } else {
  488                   metainf.registerMapping(xsElt.getQName(),
  489                           qName,
  490                           className);
  491               }
  492   
  493               // register the default value if present
  494               if (xsElt.getDefaultValue() != null){
  495                   metainf.registerDefaultValue(xsElt.getQName(),xsElt.getDefaultValue());
  496               }
  497   
  498               if (isBinary(xsElt)) {
  499                   metainf.addtStatus(xsElt.getQName(),
  500                               SchemaConstants.BINARY_TYPE);
  501               }
  502   
  503           } else if (xsElt.getRefName() != null) {
  504               // Since top level elements would not have references
  505               // and we only write toplevel elements, this should
  506               // not be a problem , atleast should not occur in a legal schema
  507           } else if (xsElt.getSchemaTypeName() != null) {
  508               QName qName = xsElt.getSchemaTypeName();
  509               String className = findClassName(qName, isArray(xsElt));
  510               metainf.registerMapping(xsElt.getQName(),
  511                       qName,
  512                       className);
  513   
  514   
  515           } else if (schemaType != null) {  //the named type should have been handled already
  516   
  517               //we are going to special case the anonymous complex type. Our algorithm for dealing
  518               //with it is to generate a single object that has the complex content inside. Really the
  519               //intent of the user when he declares the complexType anonymously is to use it privately
  520               //First copy the schema types content into the metainf holder
  521               metainf = (BeanWriterMetaInfoHolder) this.processedAnonymousComplexTypesMap.get(xsElt);
  522               metainf.setAnonymous(true);
  523           } else {
  524               //this means we did not find any schema type associated with the particular element.
  525               log.warn(SchemaCompilerMessages.getMessage("schema.elementWithNoType", xsElt.getQName().toString()));
  526               metainf.registerMapping(xsElt.getQName(),
  527                       null,
  528                       writer.getDefaultClassName(),
  529                       SchemaConstants.ANY_TYPE);
  530           }
  531   
  532           if (nillableElementList.contains(xsElt.getQName())) {
  533               metainf.registerNillableQName(xsElt.getQName());
  534           }
  535   
  536   
  537           String writtenClassName = writer.write(xsElt, processedTypemap, processedGroupTypeMap, metainf);
  538           //register the class name
  539           xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY, writtenClassName);
  540           processedElementMap.put(xsElt.getQName(), writtenClassName);
  541       }
  542   
  543       /**
  544        * For inner elements
  545        *
  546        * @param xsElt
  547        * @param innerElementMap
  548        * @param parentSchema
  549        * @throws SchemaCompilationException
  550        */
  551       private void processElement(XmlSchemaElement xsElt, Map innerElementMap, List localNillableList, XmlSchema parentSchema) throws SchemaCompilationException {
  552           processElement(xsElt, false, innerElementMap, localNillableList, parentSchema);
  553       }
  554   
  555       /**
  556        * For outer elements
  557        *
  558        * @param xsElt
  559        * @param parentSchema
  560        * @throws SchemaCompilationException
  561        */
  562       private void processElement(XmlSchemaElement xsElt, XmlSchema parentSchema) throws SchemaCompilationException {
  563           processElement(xsElt, true, null, null, parentSchema);
  564       }
  565   
  566       /**
  567        * Process and Element
  568        *
  569        * @param xsElt
  570        * @param isOuter We need to know this since the treatment of outer elements is different that
  571        *                inner elements
  572        * @throws SchemaCompilationException
  573        */
  574       private void processElement(XmlSchemaElement xsElt, boolean isOuter, Map innerElementMap, List localNillableList, XmlSchema parentSchema) throws SchemaCompilationException {
  575   
  576           //if the element is null, which usually happens when the qname is not
  577           //proper, throw an exceptions
  578           if (xsElt == null) {
  579               throw new SchemaCompilationException(
  580                       SchemaCompilerMessages.getMessage("schema.elementNull"));
  581           }
  582   
  583           //The processing element logic seems to be quite simple. Look at the relevant schema type
  584           //for each and every element and process that accordingly.
  585           //this means that any unused type definitions would not be generated!
  586           if (isOuter && processedElementList.contains(xsElt.getQName())) {
  587               return;
  588           }
  589   
  590           XmlSchemaType schemaType = xsElt.getSchemaType();
  591           if (schemaType != null) {
  592               processSchema(xsElt, schemaType, parentSchema, false);
  593               //at this time it is not wise to directly write the class for the element
  594               //so we push the complete element to an arraylist and let the process
  595               //pass through. We'll be iterating through the elements writing them
  596               //later
  597   
  598               if (!isOuter) {
  599                   if (schemaType.getName() != null) {
  600                       // this element already has a name. Which means we can directly
  601                       // register it
  602                       String className = findClassName(schemaType.getQName(),
  603                               isArray(xsElt));
  604   
  605                       innerElementMap.put(xsElt.getQName(), className);
  606   
  607                       // always store the class name in the element meta Info itself
  608                       // this details only needed by the unwrappig to set the complex type
  609                       if (options.isUseWrapperClasses() &&
  610                               PrimitiveTypeFinder.isPrimitive(className) &&
  611                               ((xsElt.getMinOccurs() == 0) || (xsElt.isNillable()))) {
  612                             className = PrimitiveTypeWrapper.getWrapper(className);
  613                       }
  614                       schemaType.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY, className);
  615                       xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY, className);
  616   
  617                       if (baseSchemaTypeMap.containsValue(className)) {
  618                           schemaType.addMetaInfo(
  619                                   SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_PRIMITVE_KEY,
  620                                   Boolean.TRUE);
  621                       }
  622                       //since this is a inner element we should add it to the inner element map
  623                   } else {
  624                       //this is an anon type. This should have been already processed and registered at
  625                       //the anon map. we've to write it just like we treat a referenced type(giving due
  626                       //care that this is meant to be an attribute in some class)
  627   
  628                       QName generatedTypeName = generateTypeQName(xsElt.getQName(), parentSchema);
  629   
  630                       if (schemaType instanceof XmlSchemaComplexType) {
  631                           //set a name
  632                           schemaType.setName(generatedTypeName.getLocalPart());
  633                           changedComplexTypeSet.add(schemaType);
  634                           // Must do this up front to support recursive types
  635                           String fullyQualifiedClassName = writer.makeFullyQualifiedClassName(schemaType.getQName());
  636                           processedTypemap.put(schemaType.getQName(), fullyQualifiedClassName);
  637   
  638                           BeanWriterMetaInfoHolder metaInfHolder = (BeanWriterMetaInfoHolder) processedAnonymousComplexTypesMap.get(xsElt);
  639                           metaInfHolder.setOwnQname(schemaType.getQName());
  640                           metaInfHolder.setOwnClassName(fullyQualifiedClassName);
  641   
  642                           writeComplexType((XmlSchemaComplexType) schemaType,
  643                                   metaInfHolder);
  644                           //remove the reference from the anon list since we named the type
  645                           processedAnonymousComplexTypesMap.remove(xsElt);
  646                           String className = findClassName(schemaType.getQName(), isArray(xsElt));
  647                           innerElementMap.put(
  648                                   xsElt.getQName(),
  649                                   className);
  650   
  651                           //store in the schema map to retrive in the unwrapping
  652                           xsElt.addMetaInfo(
  653                                   SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
  654                                   className);
  655                       } else if (schemaType instanceof XmlSchemaSimpleType) {
  656                           //set a name
  657                           schemaType.setName(generatedTypeName.getLocalPart());
  658                           changedSimpleTypeSet.add(schemaType);
  659                           // Must do this up front to support recursive types
  660                           String fullyQualifiedClassName = writer.makeFullyQualifiedClassName(schemaType.getQName());
  661                           processedTypemap.put(schemaType.getQName(), fullyQualifiedClassName);
  662   
  663                           BeanWriterMetaInfoHolder metaInfHolder = (BeanWriterMetaInfoHolder) processedAnonymousComplexTypesMap.get(xsElt);
  664                           metaInfHolder.setOwnQname(schemaType.getQName());
  665                           metaInfHolder.setOwnClassName(fullyQualifiedClassName);
  666   
  667                           writeSimpleType((XmlSchemaSimpleType) schemaType,
  668                                   metaInfHolder);
  669                           //remove the reference from the anon list since we named the type
  670                           processedAnonymousComplexTypesMap.remove(xsElt);
  671                           String className = findClassName(schemaType.getQName(), isArray(xsElt));
  672                           innerElementMap.put(
  673                                   xsElt.getQName(),
  674                                   className);
  675   
  676                           //store in the schema map
  677                           xsElt.addMetaInfo(
  678                                   SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
  679                                   className);
  680                       }
  681                   }
  682               } else {
  683                   // set the binary status of this element
  684                   this.processedElementList.add(xsElt.getQName());
  685               }
  686               //referenced name
  687           } else if (xsElt.getRefName() != null) {
  688   
  689               if (xsElt.getRefName().equals(SchemaConstants.XSD_SCHEMA)) {
  690                   innerElementMap.put(xsElt.getQName(), writer.getDefaultClassName());
  691                   return;
  692               }
  693               //process the referenced type. It could be thought that the referenced element replaces this
  694               //element
  695               XmlSchema resolvedSchema = getParentSchema(parentSchema,xsElt.getRefName(),COMPONENT_ELEMENT);
  696               if (resolvedSchema == null){
  697                   throw new SchemaCompilationException("can not find the element " + xsElt.getRefName()
  698                    + " from the parent schema " + parentSchema.getTargetNamespace());
  699               }
  700               XmlSchemaElement referencedElement = resolvedSchema.getElementByName(xsElt.getRefName());
  701               if (referencedElement == null) {
  702                   throw new SchemaCompilationException(
  703                           SchemaCompilerMessages.getMessage("schema.referencedElementNotFound", xsElt.getRefName().toString()));
  704               }
  705   
  706               // here what we want is to set the schema type name for the element
  707               if ((referencedElement.getSchemaType() != null)
  708                       && (referencedElement.getSchemaType().getQName() != null)){
  709                   // i.e this element refers to an complex type name
  710                   if (!this.processedElementRefMap.containsKey(referencedElement.getQName())) {
  711                       if (this.baseSchemaTypeMap.containsKey(referencedElement.getSchemaTypeName())) {
  712                           this.processedElementRefMap.put(referencedElement.getQName(),
  713                                   this.baseSchemaTypeMap.get(referencedElement.getSchemaTypeName()));
  714                       } else {
  715                           XmlSchema resolvedTypeSchema = getParentSchema(resolvedSchema,
  716                                   referencedElement.getSchemaTypeName(),
  717                                   COMPONENT_TYPE);
  718                           XmlSchemaType xmlSchemaType = resolvedTypeSchema.getTypeByName(
  719                                   referencedElement.getSchemaTypeName().getLocalPart());
  720                           processSchema(referencedElement, xmlSchemaType, resolvedTypeSchema, true);
  721                           this.processedElementRefMap.put(referencedElement.getQName(),
  722                                   this.processedTypemap.get(referencedElement.getSchemaTypeName()));
  723                       }
  724                   }
  725                   String javaClassName;
  726                   if (this.baseSchemaTypeMap.containsKey(referencedElement.getSchemaTypeName())) {
  727                       // here we have to do nothing since we do not generate a name
  728                   } else {
  729                       javaClassName = (String) this.processedTypemap.get(referencedElement.getSchemaTypeName());
  730                       referencedElement.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
  731                               javaClassName);
  732                       xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
  733                               javaClassName);
  734                   }
  735               } else if (referencedElement.getSchemaType() != null) {
  736                   if (!this.processedElementRefMap.containsKey(referencedElement.getQName())) {
  737   
  738                       processSchema(referencedElement, referencedElement.getSchemaType(), resolvedSchema, true);
  739                       // if this is an anonomous complex type we have to set this
  740                       this.processedElementRefMap.put(referencedElement.getQName(),
  741                               this.processedTypemap.get(referencedElement.getSchemaTypeName()));
  742   
  743                   }
  744                   
  745                   String javaClassName = (String) this.processedTypemap.get(referencedElement.getSchemaTypeName());
  746                   referencedElement.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
  747                           javaClassName);
  748                   xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
  749                           javaClassName);
  750               }
  751   
  752               // schema type name is present but not the schema type object
  753           } else if (xsElt.getSchemaTypeName() != null) {
  754               //There can be instances where the SchemaType is null but the schemaTypeName is not!
  755               //this specifically happens with xsd:anyType.
  756               QName schemaTypeName = xsElt.getSchemaTypeName();
  757   
  758               XmlSchema resolvedSchema = getParentSchema(parentSchema,schemaTypeName,COMPONENT_TYPE);
  759               XmlSchemaType typeByName = null;
  760               if (resolvedSchema != null){
  761                  typeByName = resolvedSchema.getTypeByName(schemaTypeName);
  762               }
  763   
  764               if (typeByName != null) {
  765                   //this type is found in the schema so we can process it
  766                   processSchema(xsElt, typeByName, resolvedSchema, false);
  767                   if (!isOuter) {
  768                       String className = findClassName(schemaTypeName, isArray(xsElt));
  769                       //since this is a inner element we should add it to the inner element map
  770                       innerElementMap.put(xsElt.getQName(), className);
  771                       // set the class name to be used in unwrapping
  772                       xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
  773                                   className);
  774                   } else {
  775                       this.processedElementList.add(xsElt.getQName());
  776                   }
  777               } else {
  778                   //this type is not found at all. we'll just register it with whatever the class name we can comeup with
  779                   if (!isOuter) {
  780                       String className = findClassName(schemaTypeName, isArray(xsElt));
  781                       innerElementMap.put(xsElt.getQName(), className);
  782                       // set the class name to be used in unwrapping
  783                       xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
  784                                   className);
  785                   } else {
  786                       this.processedElementList.add(xsElt.getQName());
  787                   }
  788               }
  789           }
  790   
  791           //add this elements QName to the nillable group if it has the  nillable attribute
  792           if (xsElt.isNillable()) {
  793               if (isOuter) {
  794                   this.nillableElementList.add(xsElt.getQName());
  795               } else {
  796                   localNillableList.add(xsElt.getQName());
  797               }
  798           }
  799   
  800       }
  801   
  802       /**
  803        * Generate a unique type Qname using an element name
  804        *
  805        * @param referenceEltQName
  806        * @param parentSchema
  807        */
  808       private QName generateTypeQName(QName referenceEltQName, XmlSchema parentSchema) {
  809           QName generatedTypeName = new QName(referenceEltQName.getNamespaceURI(),
  810                   referenceEltQName.getLocalPart() + getNextTypeSuffix(referenceEltQName.getLocalPart()));
  811           while (parentSchema.getTypeByName(generatedTypeName) != null) {
  812               generatedTypeName = new QName(referenceEltQName.getNamespaceURI(),
  813                       referenceEltQName.getLocalPart() + getNextTypeSuffix(referenceEltQName.getLocalPart()));
  814           }
  815           return generatedTypeName;
  816       }
  817   
  818       /**
  819        * Finds whether a given class is already made
  820        *
  821        * @param qName
  822        */
  823       private boolean isAlreadyProcessed(QName qName) {
  824           return processedTypemap.containsKey(qName) ||
  825                   simpleTypesMap.containsKey(qName) ||
  826                   baseSchemaTypeMap.containsKey(qName) ||
  827                   processedGroupTypeMap.containsKey(qName);
  828       }
  829   
  830   
  831       /**
  832        * A method to pick the ref class name
  833        *
  834        * @param name
  835        * @param isArray
  836        */
  837       private String findRefClassName(QName name, boolean isArray) {
  838           String className = null;
  839           if (processedElementRefMap.get(name) != null) {
  840               className = (String) processedElementRefMap.get(name);
  841   
  842               if (isArray) {
  843                   //append the square braces that say this is an array
  844                   //hope this works for all cases!!!!!!!
  845                   //todo this however is a thing that needs to be
  846                   //todo fixed to get complete language support
  847                   className = className + "[]";
  848               }
  849           }
  850           return className;
  851   
  852       }
  853   
  854       /**
  855        * Finds a class name from the given Qname
  856        *
  857        * @param qName
  858        * @param isArray
  859        * @return FQCN
  860        */
  861       private String findClassName(QName qName, boolean isArray) throws SchemaCompilationException {
  862   
  863           //find the class name
  864           String className;
  865           if (processedTypemap.containsKey(qName)) {
  866               className = (String) processedTypemap.get(qName);
  867           } else if (simpleTypesMap.containsKey(qName)) {
  868               className = (String) simpleTypesMap.get(qName);
  869           } else if (baseSchemaTypeMap.containsKey(qName)) {
  870               className = (String) baseSchemaTypeMap.get(qName);
  871           } else {
  872               if (isSOAP_ENC(qName.getNamespaceURI())) {
  873                   throw new SchemaCompilationException(SchemaCompilerMessages.getMessage("schema.soapencoding.error", qName.toString()));
  874   
  875               }
  876               // We seem to have failed in finding a class name for the
  877               //contained schema type. We better set the default then
  878               //however it's better if the default can be set through the
  879               //property file
  880               className = writer.getDefaultClassName();
  881               log.warn(SchemaCompilerMessages
  882                       .getMessage("schema.typeMissing", qName.toString()));
  883           }
  884   
  885           if (isArray) {
  886               //append the square braces that say this is an array
  887               //hope this works for all cases!!!!!!!
  888               //todo this however is a thing that needs to be
  889               //todo fixed to get complete language support
  890               className = className + "[]";
  891           }
  892           return className;
  893       }
  894   
  895       /**
  896        * Returns true if SOAP_ENC Namespace.
  897        *
  898        * @param s a string representing the URI to check
  899        * @return true if <code>s</code> matches a SOAP ENCODING namespace URI,
  900        *         false otherwise
  901        */
  902       public static boolean isSOAP_ENC(String s) {
  903           if (s.equals(Constants.URI_SOAP11_ENC))
  904               return true;
  905           return s.equals(Constants.URI_SOAP12_ENC);
  906       }
  907   
  908       /**
  909        * Process a schema element which has been refered to by an element
  910        *
  911        * @param schemaType
  912        * @throws SchemaCompilationException
  913        */
  914       private void processSchema(XmlSchemaElement xsElt,
  915                                  XmlSchemaType schemaType,
  916                                  XmlSchema parentSchema,
  917                                  boolean isWriteAnonComplexType) throws SchemaCompilationException {
  918           if (schemaType instanceof XmlSchemaComplexType) {
  919               //write classes for complex types
  920               XmlSchemaComplexType complexType = (XmlSchemaComplexType) schemaType;
  921               // complex type name may not be null if we have set it
  922               if (complexType.getName() != null && !this.changedComplexTypeSet.contains(schemaType)) {
  923                   // here complex type may be in another shcema so we have to find the
  924                   // correct parent schema.
  925                   XmlSchema resolvedSchema = getParentSchema(parentSchema,complexType.getQName(),COMPONENT_TYPE);
  926                   if (resolvedSchema == null){
  927                       throw new SchemaCompilationException("can not find the parent schema for the " +
  928                               "complex type " + complexType.getQName() + " from the parent schema " +
  929                       parentSchema.getTargetNamespace());
  930                   } else {
  931                      processNamedComplexSchemaType(complexType, resolvedSchema);
  932                   }
  933               } else {
  934                   processAnonymousComplexSchemaType(xsElt, complexType, parentSchema, isWriteAnonComplexType);
  935               }
  936           } else if (schemaType instanceof XmlSchemaSimpleType) {
  937               //process simple type
  938               processSimpleSchemaType((XmlSchemaSimpleType) schemaType,
  939                       xsElt,
  940                       parentSchema, null);
  941           }
  942       }
  943   
  944   
  945       /**
  946        * @param complexType
  947        * @throws SchemaCompilationException
  948        */
  949       private void processAnonymousComplexSchemaType(XmlSchemaElement elt,
  950                                                      XmlSchemaComplexType complexType,
  951                                                      XmlSchema parentSchema,
  952                                                      boolean isWriteAnonComplexType)
  953               throws SchemaCompilationException {
  954   
  955           //here we have a problem when processing the circulare element
  956           // references if we differ this processing
  957           // generate a name to the complex type and register it here
  958           QName generatedTypeName = null;
  959           String javaClassName = null;
  960           if (isWriteAnonComplexType) {
  961   
  962               generatedTypeName = generateTypeQName(elt.getQName(), parentSchema);
  963   
  964               if (elt.getSchemaTypeName() == null) {
  965                   elt.setSchemaTypeName(generatedTypeName);
  966                   this.changedElementSet.add(elt);
  967               }
  968   
  969               //set a name
  970               complexType.setName(generatedTypeName.getLocalPart());
  971               this.changedComplexTypeSet.add(complexType);
  972   
  973               javaClassName = writer.makeFullyQualifiedClassName(generatedTypeName);
  974               processedTypemap.put(generatedTypeName, javaClassName);
  975               this.processedElementRefMap.put(elt.getQName(), javaClassName);
  976               complexType.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY, javaClassName);
  977           }
  978   
  979   
  980           BeanWriterMetaInfoHolder metaInfHolder = processComplexType(elt.getQName(),complexType, parentSchema);
  981   
  982           // here the only difference is that we generate the class
  983           // irrespective of where we need it or not
  984           if (isWriteAnonComplexType) {
  985               metaInfHolder.setOwnClassName(javaClassName);
  986               metaInfHolder.setOwnQname(generatedTypeName);
  987               writeComplexType(complexType, metaInfHolder);
  988           }
  989   
  990           //since this is a special case (an unnamed complex type) we'll put the already processed
  991           //metainf holder in a special map to be used later
  992           this.processedAnonymousComplexTypesMap.put(elt, metaInfHolder);
  993   
  994       }
  995   
  996       /**
  997        * handle the complex types which are named
  998        *
  999        * @param complexType
 1000        */
 1001       private void processNamedComplexSchemaType(XmlSchemaComplexType complexType,
 1002                                                  XmlSchema parentSchema) throws SchemaCompilationException {
 1003   
 1004           if (processedTypemap.containsKey(complexType.getQName())
 1005                   || baseSchemaTypeMap.containsKey(complexType.getQName())) {
 1006               return;
 1007           }
 1008   
 1009           // Must do this up front to support recursive types
 1010           String fullyQualifiedClassName = writer.makeFullyQualifiedClassName(complexType.getQName());
 1011           processedTypemap.put(complexType.getQName(), fullyQualifiedClassName);
 1012   
 1013           //register that in the schema metainfo bag
 1014           complexType.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
 1015                   fullyQualifiedClassName);
 1016   
 1017           BeanWriterMetaInfoHolder metaInfHolder = processComplexType(complexType.getQName(),complexType, parentSchema);
 1018           //add this information to the metainfo holder
 1019           metaInfHolder.setOwnQname(complexType.getQName());
 1020           metaInfHolder.setOwnClassName(fullyQualifiedClassName);
 1021           //write the class. This type mapping would have been populated right now
 1022           //Note - We always write classes for named complex types
 1023           writeComplexType(complexType, metaInfHolder);
 1024   
 1025   
 1026       }
 1027   
 1028       /**
 1029        * Writes a complex type
 1030        *
 1031        * @param complexType
 1032        * @param metaInfHolder
 1033        * @throws SchemaCompilationException
 1034        */
 1035       private String writeComplexType(XmlSchemaComplexType complexType, BeanWriterMetaInfoHolder metaInfHolder)
 1036               throws SchemaCompilationException {
 1037           String javaClassName = writer.write(complexType.getQName(),
 1038                   processedTypemap, processedGroupTypeMap, metaInfHolder, complexType.isAbstract());
 1039           processedTypeMetaInfoMap.put(complexType.getQName(), metaInfHolder);
 1040           return javaClassName;
 1041       }
 1042   
 1043   
 1044       /**
 1045        * Writes complex Sequence,Choice, all elements
 1046        * @param qname complex type qname
 1047        * @param metaInfHolder
 1048        * @return  written java class name
 1049        * @throws SchemaCompilationException
 1050        */
 1051   
 1052   
 1053       private String writeComplexParticle(QName qname,BeanWriterMetaInfoHolder metaInfHolder)
 1054               throws SchemaCompilationException {
 1055          String javaClassName = writer.write(qname, processedTypemap, processedGroupTypeMap, metaInfHolder,false);
 1056           processedTypeMetaInfoMap.put(qname, metaInfHolder);
 1057           return javaClassName;
 1058       }
 1059   
 1060       /**
 1061        * Writes a complex type
 1062        *
 1063        * @param simpleType
 1064        * @param metaInfHolder
 1065        * @throws SchemaCompilationException
 1066        */
 1067       private void writeSimpleType(XmlSchemaSimpleType simpleType, BeanWriterMetaInfoHolder metaInfHolder)
 1068               throws SchemaCompilationException {
 1069           writer.write(simpleType, processedTypemap, processedGroupTypeMap, metaInfHolder);
 1070           processedTypeMetaInfoMap.put(simpleType.getQName(), metaInfHolder);
 1071       }
 1072   
 1073       private BeanWriterMetaInfoHolder processComplexType(
 1074               QName parentElementQName,
 1075               XmlSchemaComplexType complexType,
 1076               XmlSchema parentSchema) throws SchemaCompilationException {
 1077           XmlSchemaParticle particle = complexType.getParticle();
 1078           BeanWriterMetaInfoHolder metaInfHolder = new BeanWriterMetaInfoHolder();
 1079           if (particle != null) {
 1080               //Process the particle
 1081               processParticle(parentElementQName, particle, metaInfHolder, parentSchema);
 1082           }
 1083   
 1084           //process attributes - first look for the explicit attributes
 1085           processAttributes(complexType.getAttributes(),metaInfHolder,parentSchema);
 1086   
 1087           //process any attribute
 1088           //somehow the xml schema parser does not seem to pickup the any attribute!!
 1089           XmlSchemaAnyAttribute anyAtt = complexType.getAnyAttribute();
 1090           if (anyAtt != null) {
 1091               processAnyAttribute(metaInfHolder, anyAtt);
 1092           }
 1093   
 1094   
 1095           //process content ,either  complex or simple
 1096           if (complexType.getContentModel() != null) {
 1097               processContentModel(complexType.getContentModel(),
 1098                       metaInfHolder,
 1099                       parentSchema);
 1100           }
 1101           return metaInfHolder;
 1102       }
 1103   
 1104       private void processAttributes(XmlSchemaObjectCollection attributes,
 1105                                      BeanWriterMetaInfoHolder metaInfHolder,
 1106                                      XmlSchema parentSchema) throws SchemaCompilationException {
 1107           Iterator attribIterator = attributes.getIterator();
 1108           while (attribIterator.hasNext()) {
 1109               Object o = attribIterator.next();
 1110               if (o instanceof XmlSchemaAttribute) {
 1111                   processAttribute((XmlSchemaAttribute) o, metaInfHolder, parentSchema);
 1112               } else if (o instanceof XmlSchemaAttributeGroupRef){
 1113                   processAttributeGroupReference((XmlSchemaAttributeGroupRef)o,metaInfHolder,parentSchema);
 1114               }
 1115           }
 1116       }
 1117   
 1118       private void processAttributeGroupReference(XmlSchemaAttributeGroupRef attributeGroupRef,
 1119                                                   BeanWriterMetaInfoHolder metaInfHolder,
 1120                                                   XmlSchema parentSchema) throws SchemaCompilationException {
 1121   
 1122           QName attributeGroupRefName = attributeGroupRef.getRefName();
 1123           if (attributeGroupRefName != null){
 1124              XmlSchema resolvedSchema = getParentSchema(parentSchema,attributeGroupRefName,COMPONENT_ATTRIBUTE_GROUP);
 1125               if (resolvedSchema == null) {
 1126                   throw new SchemaCompilationException("can not find the attribute group reference name " +
 1127                           attributeGroupRefName + " from the parent schema " + parentSchema.getTargetNamespace());
 1128               } else {
 1129                   XmlSchemaAttributeGroup xmlSchemaAttributeGroup =
 1130                           (XmlSchemaAttributeGroup) resolvedSchema.getAttributeGroups().getItem(attributeGroupRefName);
 1131                   if (xmlSchemaAttributeGroup != null) {
 1132                       processAttributes(xmlSchemaAttributeGroup.getAttributes(), metaInfHolder, resolvedSchema);
 1133                   } else {
 1134                       throw new SchemaCompilationException("Can not find an attribute group for group reference "
 1135                               + attributeGroupRefName.getLocalPart());
 1136                   }
 1137               }
 1138   
 1139           } else {
 1140               throw new SchemaCompilationException("No group refernce has given");
 1141           }
 1142       }
 1143   
 1144       /**
 1145        * Process the content models. A content model is either simple type or a complex type
 1146        * and included inside a complex content
 1147        */
 1148       private void processContentModel(XmlSchemaContentModel content,
 1149                                        BeanWriterMetaInfoHolder metaInfHolder,
 1150                                        XmlSchema parentSchema)
 1151               throws SchemaCompilationException {
 1152           if (content instanceof XmlSchemaComplexContent) {
 1153               processComplexContent((XmlSchemaComplexContent) content, metaInfHolder, parentSchema);
 1154           } else if (content instanceof XmlSchemaSimpleContent) {
 1155               processSimpleContent((XmlSchemaSimpleContent) content, metaInfHolder, parentSchema);
 1156           }
 1157       }
 1158   
 1159       /**
 1160        * Prcess the complex content
 1161        */
 1162       private void processComplexContent(XmlSchemaComplexContent complexContent,
 1163                                          BeanWriterMetaInfoHolder metaInfHolder,
 1164                                          XmlSchema parentSchema)
 1165               throws SchemaCompilationException {
 1166           XmlSchemaContent content = complexContent.getContent();
 1167   
 1168           if (content instanceof XmlSchemaComplexContentExtension) {
 1169   
 1170               // to handle extension we need to attach the extended items to the base type
 1171               // and create a new type
 1172               XmlSchemaComplexContentExtension extension = (XmlSchemaComplexContentExtension)content;
 1173   
 1174               //process the base type if it has not been processed yet
 1175               if (!isAlreadyProcessed(extension.getBaseTypeName())) {
 1176                   //pick the relevant basetype from the schema and process it
 1177                   XmlSchema resolvedSchema = getParentSchema(parentSchema, extension.getBaseTypeName(), COMPONENT_TYPE);
 1178                   if (resolvedSchema == null) {
 1179                       throw new SchemaCompilationException("can not find the compley type " + extension.getBaseTypeName()
 1180                               + " from the parent type " + parentSchema.getTargetNamespace());
 1181                   } else {
 1182                       XmlSchemaType type = resolvedSchema.getTypeByName(extension.getBaseTypeName());
 1183                       if (type instanceof XmlSchemaComplexType) {
 1184                           XmlSchemaComplexType complexType = (XmlSchemaComplexType) type;
 1185                           if (complexType.getName() != null) {
 1186                               processNamedComplexSchemaType(complexType, resolvedSchema);
 1187                           } else {
 1188                               //this is not possible. The extension should always
 1189                               //have a name
 1190                               throw new SchemaCompilationException("Unnamed complex type used in extension");//Internationlize this
 1191                           }
 1192                       } else if (type instanceof XmlSchemaSimpleType) {
 1193                           //process simple type
 1194                           processSimpleSchemaType((XmlSchemaSimpleType) type, null, resolvedSchema, null);
 1195                       }
 1196                   }
 1197   
 1198               }
 1199   
 1200               // before actually processing this node, we need to recurse through the base types and add their
 1201               // children (sometimes even preserving the order) to the metainfo holder of this type
 1202               // the reason is that for extensions, the prefered way is to have the sequences of the base class
 1203               //* before * the sequence of the child element.
 1204               copyMetaInfoHierarchy(metaInfHolder, extension.getBaseTypeName(), parentSchema);
 1205   
 1206               //process the particle of this node
 1207               if (extension.getParticle() != null) {
 1208                   processParticle(extension.getBaseTypeName(),extension.getParticle(), metaInfHolder, parentSchema);
 1209               }
 1210   
 1211               // process attributes
 1212               //process attributes - first look for the explicit attributes
 1213               processAttributes(extension.getAttributes(),metaInfHolder,parentSchema);
 1214   
 1215               //process any attribute
 1216               //somehow the xml schema parser does not seem to pickup the any attribute!!
 1217               XmlSchemaAnyAttribute anyAtt = extension.getAnyAttribute();
 1218               if (anyAtt != null) {
 1219                   processAnyAttribute(metaInfHolder, anyAtt);
 1220               }
 1221               String className = findClassName(extension.getBaseTypeName(), false);
 1222   
 1223               if (!writer.getDefaultClassName().equals(className)) {
 1224                   //the particle has been processed, However since this is an extension we need to
 1225                   //add the basetype as an extension to the complex type class.
 1226                   // The basetype has been processed already
 1227                   metaInfHolder.setExtension(true);
 1228                   metaInfHolder.setExtensionClassName(className);
 1229                   //Note  - this is no array! so the array boolean is false
 1230               }
 1231           } else if (content instanceof XmlSchemaComplexContentRestriction) {
 1232               XmlSchemaComplexContentRestriction restriction = (XmlSchemaComplexContentRestriction) content;
 1233   
 1234               //process the base type if it has not been processed yet
 1235               if (!isAlreadyProcessed(restriction.getBaseTypeName())) {
 1236                   //pick the relevant basetype from the schema and process it
 1237                   XmlSchema resolvedSchema = getParentSchema(parentSchema, restriction.getBaseTypeName(), COMPONENT_TYPE);
 1238                   if (resolvedSchema == null) {
 1239                       throw new SchemaCompilationException("can not find the complex type " + restriction.getBaseTypeName()
 1240                               + " from the parent type " + parentSchema.getTargetNamespace());
 1241                   } else {
 1242                       XmlSchemaType type = resolvedSchema.getTypeByName(restriction.getBaseTypeName());
 1243                       if (type instanceof XmlSchemaComplexType) {
 1244                           XmlSchemaComplexType complexType = (XmlSchemaComplexType) type;
 1245                           if (complexType.getName() != null) {
 1246                               processNamedComplexSchemaType(complexType, resolvedSchema);
 1247                           } else {
 1248                               //this is not possible. The restriction should always
 1249                               //have a name
 1250                               throw new SchemaCompilationException("Unnamed complex type used in restriction");//Internationlize this
 1251                           }
 1252                       } else if (type instanceof XmlSchemaSimpleType) {
 1253                           throw new SchemaCompilationException("Not a valid restriction, complex content restriction base type cannot be a simple type.");
 1254                       }
 1255                   }
 1256               }
 1257   
 1258               copyMetaInfoHierarchy(metaInfHolder, restriction.getBaseTypeName(), parentSchema);
 1259   
 1260               //process the particle of this node
 1261               processParticle(restriction.getBaseTypeName(),restriction.getParticle(), metaInfHolder, parentSchema);
 1262   
 1263               //process attributes - first look for the explicit attributes
 1264               processAttributes(restriction.getAttributes(),metaInfHolder,parentSchema);
 1265   
 1266               //process any attribute
 1267               //somehow the xml schema parser does not seem to pickup the any attribute!!
 1268               XmlSchemaAnyAttribute anyAtt = restriction.getAnyAttribute();
 1269               if (anyAtt != null) {
 1270                   processAnyAttribute(metaInfHolder, anyAtt);
 1271               }
 1272               String className = findClassName(restriction.getBaseTypeName(), false);
 1273   
 1274               if (!writer.getDefaultClassName().equals(className)) {
 1275                   metaInfHolder.setRestriction(true);
 1276                   metaInfHolder.setRestrictionClassName(findClassName(restriction.getBaseTypeName(), false));
 1277                   //Note  - this is no array! so the array boolean is false
 1278               }
 1279           }
 1280       }
 1281   
 1282       /**
 1283        * Recursive method to populate the metainfo holders with info from the base types
 1284        *
 1285        * @param metaInfHolder
 1286        * @param baseTypeName
 1287        * @param parentSchema
 1288        */
 1289       private void copyMetaInfoHierarchy(BeanWriterMetaInfoHolder metaInfHolder,
 1290                                          QName baseTypeName,
 1291                                          XmlSchema parentSchema)
 1292               throws SchemaCompilationException {
 1293   
 1294           XmlSchema resolvedSchema = getParentSchema(parentSchema,baseTypeName,COMPONENT_TYPE);
 1295           if (resolvedSchema == null) {
 1296               throw new SchemaCompilationException("can not find type " + baseTypeName
 1297                       + " from the parent schema " + parentSchema.getTargetNamespace());
 1298           } else {
 1299               XmlSchemaType type = resolvedSchema.getTypeByName(baseTypeName);
 1300               BeanWriterMetaInfoHolder baseMetaInfoHolder = (BeanWriterMetaInfoHolder)
 1301                       processedTypeMetaInfoMap.get(baseTypeName);
 1302   
 1303   
 1304               if (baseMetaInfoHolder != null) {
 1305   
 1306                   // see whether this type is also extended from some other type first
 1307                   // if so proceed to set their parents as well.
 1308                   if (type instanceof XmlSchemaComplexType) {
 1309                       XmlSchemaComplexType complexType = (XmlSchemaComplexType) type;
 1310                       if (complexType.getContentModel() != null) {
 1311                           XmlSchemaContentModel content = complexType.getContentModel();
 1312                           if (content instanceof XmlSchemaComplexContent) {
 1313                               XmlSchemaComplexContent complexContent =
 1314                                       (XmlSchemaComplexContent) content;
 1315                               if (complexContent.getContent() instanceof XmlSchemaComplexContentExtension) {
 1316                                   XmlSchemaComplexContentExtension extension =
 1317                                           (XmlSchemaComplexContentExtension) complexContent.getContent();
 1318                                   //recursively call the copyMetaInfoHierarchy method
 1319                                   copyMetaInfoHierarchy(baseMetaInfoHolder,
 1320                                           extension.getBaseTypeName(),
 1321                                           resolvedSchema);
 1322   
 1323                               } else if (complexContent.getContent() instanceof XmlSchemaComplexContentRestriction) {
 1324   
 1325                                   XmlSchemaComplexContentRestriction restriction =
 1326                                           (XmlSchemaComplexContentRestriction) complexContent.getContent();
 1327                                   //recursively call the copyMetaInfoHierarchy method
 1328                                   copyMetaInfoHierarchy(baseMetaInfoHolder,
 1329                                           restriction.getBaseTypeName(),
 1330                                           resolvedSchema);
 1331   
 1332                               } else {
 1333                                   throw new SchemaCompilationException(
 1334                                           SchemaCompilerMessages.getMessage("schema.unknowncontenterror"));
 1335                               }
 1336   
 1337                           } else if (content instanceof XmlSchemaSimpleContent) {
 1338                               throw new SchemaCompilationException(
 1339                                       SchemaCompilerMessages.getMessage("schema.unsupportedcontenterror", "Simple Content"));
 1340                           } else {
 1341                               throw new SchemaCompilationException(
 1342                                       SchemaCompilerMessages.getMessage("schema.unknowncontenterror"));
 1343                           }
 1344                       }
 1345                       //Do the actual parent setting
 1346                       metaInfHolder.setAsParent(baseMetaInfoHolder);
 1347   
 1348                   } else if (type instanceof XmlSchemaSimpleType) {
 1349   
 1350                       // we have to copy the uion data if the parent simple type restriction
 1351                       // is an union
 1352                       // this union attribute is copied from the child to parent to genrate the parent
 1353                       // code as union
 1354                       if (baseMetaInfoHolder.isUnion()) {
 1355                           metaInfHolder.setUnion(true);
 1356                           Map memberTypes = baseMetaInfoHolder.getMemberTypes();
 1357                           Object qname;
 1358                           for (Iterator iter = memberTypes.keySet().iterator(); iter.hasNext();) {
 1359                               qname = iter.next();
 1360                               metaInfHolder.addMemberType((QName) qname, (String) memberTypes.get(qname));
 1361                           }
 1362                       }
 1363   
 1364                       // we have to copy the list type data to parent if it is a list
 1365                       if (baseMetaInfoHolder.isList()) {
 1366                           metaInfHolder.setList(true);
 1367                           metaInfHolder.setItemTypeQName(baseMetaInfoHolder.getItemTypeQName());
 1368                           metaInfHolder.setItemTypeClassName(baseMetaInfoHolder.getItemTypeClassName());
 1369                       }
 1370                       metaInfHolder.setAsParent(baseMetaInfoHolder);
 1371                   }
 1372   
 1373               }
 1374           }
 1375       }
 1376   
 1377       /**
 1378        * @param simpleContent
 1379        * @param metaInfHolder
 1380        * @throws SchemaCompilationException
 1381        */
 1382       private void processSimpleContent(XmlSchemaSimpleContent simpleContent, BeanWriterMetaInfoHolder metaInfHolder, XmlSchema parentSchema)
 1383               throws SchemaCompilationException {
 1384           XmlSchemaContent content;
 1385           content = simpleContent.getContent();
 1386           if (content instanceof XmlSchemaSimpleContentExtension) {
 1387               XmlSchemaSimpleContentExtension extension = (XmlSchemaSimpleContentExtension) content;
 1388   
 1389               //process the base type if it has not been processed yet
 1390               if (!isAlreadyProcessed(extension.getBaseTypeName())) {
 1391                   //pick the relevant basetype from the schema and process it
 1392                   XmlSchema resolvedSchema = getParentSchema(parentSchema, extension.getBaseTypeName(), COMPONENT_TYPE);
 1393                   if (resolvedSchema == null) {
 1394                       throw new SchemaCompilationException("can not find type " + extension.getBaseTypeName()
 1395                               + " from the parent schema " + parentSchema.getTargetNamespace());
 1396                   } else {
 1397                       XmlSchemaType type = resolvedSchema.getTypeByName(extension.getBaseTypeName());
 1398                       if (type instanceof XmlSchemaComplexType) {
 1399                           XmlSchemaComplexType complexType = (XmlSchemaComplexType) type;
 1400                           if (complexType.getName() != null) {
 1401                               processNamedComplexSchemaType(complexType, resolvedSchema);
 1402                           } else {
 1403                               //this is not possible. The extension should always
 1404                               //have a name
 1405                               throw new SchemaCompilationException("Unnamed complex type used in extension");//Internationlize this
 1406                           }
 1407                       } else if (type instanceof XmlSchemaSimpleType) {
 1408                           //process simple type
 1409                           processSimpleSchemaType((XmlSchemaSimpleType) type, null, resolvedSchema, null);
 1410                       }
 1411                   }
 1412   
 1413               }
 1414   
 1415               //process extension base type
 1416               processSimpleExtensionBaseType(extension.getBaseTypeName(), metaInfHolder, parentSchema);
 1417   
 1418               //process attributes
 1419               XmlSchemaObjectCollection attribs = extension.getAttributes();
 1420               Iterator attribIterator = attribs.getIterator();
 1421               while (attribIterator.hasNext()) {
 1422                   Object attr = attribIterator.next();
 1423                   if (attr instanceof XmlSchemaAttribute) {
 1424                       processAttribute((XmlSchemaAttribute) attr, metaInfHolder, parentSchema);
 1425   
 1426                   }
 1427               }
 1428   
 1429               //process any attribute
 1430               XmlSchemaAnyAttribute anyAtt = extension.getAnyAttribute();
 1431               if (anyAtt != null) {
 1432                   processAnyAttribute(metaInfHolder, anyAtt);
 1433               }
 1434   
 1435           } else if (content instanceof XmlSchemaSimpleContentRestriction) {
 1436               XmlSchemaSimpleContentRestriction restriction = (XmlSchemaSimpleContentRestriction) content;
 1437   
 1438               //process the base type if it has not been processed yet
 1439               if (!isAlreadyProcessed(restriction.getBaseTypeName())) {
 1440                   //pick the relevant basetype from the schema and process it
 1441                   XmlSchema resolvedSchema = getParentSchema(parentSchema, restriction.getBaseTypeName(), COMPONENT_TYPE);
 1442                   if (resolvedSchema == null) {
 1443                       throw new SchemaCompilationException("can not find type " + restriction.getBaseTypeName()
 1444                               + " from the parent schema " + parentSchema.getTargetNamespace());
 1445                   } else {
 1446                       XmlSchemaType type = resolvedSchema.getTypeByName(restriction.getBaseTypeName());
 1447   
 1448                       if (type instanceof XmlSchemaComplexType) {
 1449                           XmlSchemaComplexType complexType = (XmlSchemaComplexType) type;
 1450                           if (complexType.getName() != null) {
 1451                               processNamedComplexSchemaType(complexType, resolvedSchema);
 1452                           } else {
 1453                               //this is not possible. The extension should always
 1454                               //have a name
 1455                               throw new SchemaCompilationException("Unnamed complex type used in restriction");//Internationlize this
 1456                           }
 1457                       } else if (type instanceof XmlSchemaSimpleType) {
 1458                           //process simple type
 1459                           processSimpleSchemaType((XmlSchemaSimpleType) type, null, resolvedSchema, null);
 1460                       }
 1461                   }
 1462   
 1463               }
 1464               //process restriction base type
 1465               processSimpleRestrictionBaseType(restriction.getBaseTypeName(),
 1466                       restriction.getBaseTypeName(),
 1467                       metaInfHolder,
 1468                       parentSchema);
 1469               metaInfHolder.setSimple(true);
 1470           }
 1471       }
 1472   
 1473       /**
 1474        * Process Simple Extension Base Type.
 1475        *
 1476        * @param extBaseType
 1477        * @param metaInfHolder
 1478        */
 1479       public void processSimpleExtensionBaseType(QName extBaseType,
 1480                                                  BeanWriterMetaInfoHolder metaInfHolder,
 1481                                                  XmlSchema parentSchema) throws SchemaCompilationException {
 1482   
 1483           //find the class name
 1484           String className = findClassName(extBaseType, false);
 1485   
 1486           // if the base type is an primitive then we do not have to extend them
 1487           // and it is considered as a property
 1488           // on the otherhand if the base type is an generated class then we have to
 1489           // extend from it
 1490   
 1491           if (baseSchemaTypeMap.containsKey(extBaseType)) {
 1492               //this means the schema type actually returns a different QName
 1493               if (changedTypeMap.containsKey(extBaseType)) {
 1494                   metaInfHolder.registerMapping(extBaseType,
 1495                           (QName) changedTypeMap.get(extBaseType),
 1496                           className, SchemaConstants.ELEMENT_TYPE);
 1497               } else {
 1498                   metaInfHolder.registerMapping(extBaseType,
 1499                           extBaseType,
 1500                           className, SchemaConstants.ELEMENT_TYPE);
 1501               }
 1502               metaInfHolder.setSimple(true);
 1503               // we have already process when it comes to this place
 1504           } else if (processedTypemap.containsKey(extBaseType)) {
 1505               //set the extension base class name
 1506               XmlSchema resolvedSchema = getParentSchema(parentSchema,extBaseType,COMPONENT_TYPE);
 1507               if (resolvedSchema == null) {
 1508                   throw new SchemaCompilationException("can not find the type " + extBaseType
 1509                           + " from the parent schema " + parentSchema.getTargetNamespace());
 1510               } else {
 1511                   XmlSchemaType type = resolvedSchema.getTypeByName(extBaseType);
 1512                   if (type instanceof XmlSchemaSimpleType) {
 1513                       metaInfHolder.setSimple(true);
 1514                       metaInfHolder.setExtension(true);
 1515                       metaInfHolder.setExtensionClassName(className);
 1516   
 1517                       copyMetaInfoHierarchy(metaInfHolder, extBaseType, resolvedSchema);
 1518                   } else if (type instanceof XmlSchemaComplexType) {
 1519                       XmlSchemaComplexType complexType = (XmlSchemaComplexType) type;
 1520                       if (complexType.getContentModel() == null) {
 1521                           // do not set as a simple type since we want to
 1522                           // print the element names
 1523                           metaInfHolder.setExtension(true);
 1524                           metaInfHolder.setExtensionClassName(className);
 1525                           copyMetaInfoHierarchy(metaInfHolder, extBaseType, resolvedSchema);
 1526                       }
 1527                   }
 1528               }
 1529   
 1530           } else {
 1531               metaInfHolder.setSimple(true);
 1532           }
 1533   
 1534           //get the binary state and add that to the status map
 1535           if (isBinary(extBaseType)) {
 1536               metaInfHolder.addtStatus(extBaseType,
 1537                       SchemaConstants.BINARY_TYPE);
 1538           }
 1539       }
 1540   
 1541       /**
 1542        * Process Simple Restriction Base Type.
 1543        *
 1544        * @param resBaseType
 1545        * @param metaInfHolder
 1546        */
 1547       public void processSimpleRestrictionBaseType(QName qName,
 1548                                                    QName resBaseType,
 1549                                                    BeanWriterMetaInfoHolder metaInfHolder,
 1550                                                    XmlSchema parentSchema) throws SchemaCompilationException {
 1551   
 1552           //find the class name
 1553           String className = findClassName(resBaseType, false);
 1554   
 1555           //this means the schema type actually returns a different QName
 1556           if (baseSchemaTypeMap.containsKey(resBaseType)) {
 1557               if (changedTypeMap.containsKey(resBaseType)) {
 1558                   metaInfHolder.registerMapping(qName,
 1559                           (QName) changedTypeMap.get(resBaseType),
 1560                           className, SchemaConstants.ELEMENT_TYPE);
 1561               } else {
 1562                   metaInfHolder.registerMapping(qName,
 1563                           resBaseType,
 1564                           className, SchemaConstants.ELEMENT_TYPE);
 1565               }
 1566           } else if (processedTypemap.containsKey(resBaseType)) {
 1567               //this is not a standared type
 1568               // so the parent class must extend it
 1569               metaInfHolder.setSimple(true);
 1570               metaInfHolder.setRestriction(true);
 1571               metaInfHolder.setRestrictionClassName(className);
 1572               copyMetaInfoHierarchy(metaInfHolder, resBaseType, parentSchema);
 1573           }
 1574   
 1575           metaInfHolder.setRestrictionBaseType(resBaseType);
 1576   
 1577   
 1578       }
 1579   
 1580       /**
 1581        * Process Facets.
 1582        *
 1583        * @param metaInfHolder
 1584        */
 1585       private void processFacets(XmlSchemaSimpleTypeRestriction restriction,
 1586                                  BeanWriterMetaInfoHolder metaInfHolder,
 1587                                  XmlSchema parentSchema) {
 1588   
 1589           XmlSchemaObjectCollection facets = restriction.getFacets();
 1590           Iterator facetIterator = facets.getIterator();
 1591   
 1592           while (facetIterator.hasNext()) {
 1593               Object obj = facetIterator.next();
 1594   
 1595               if (obj instanceof XmlSchemaPatternFacet) {
 1596                   XmlSchemaPatternFacet pattern = (XmlSchemaPatternFacet) obj;
 1597                   // some patterns contain \ so we have to replace them
 1598                   String patternString = pattern.getValue().toString();
 1599                   // replace backword slashes
 1600                   patternString = patternString.replaceAll("\\\\", "\\\\\\\\");
 1601                   if ((metaInfHolder.getPatternFacet() != null) &&
 1602                           (metaInfHolder.getPatternFacet().trim().length() > 0)){
 1603                       // i.e there is a pattern faceset
 1604                       patternString = metaInfHolder.getPatternFacet().trim() + "|" + patternString;
 1605                   }
 1606                   metaInfHolder.setPatternFacet(patternString);
 1607               }
 1608   
 1609               else if (obj instanceof XmlSchemaEnumerationFacet) {
 1610                   XmlSchemaEnumerationFacet enumeration = (XmlSchemaEnumerationFacet) obj;
 1611                   if (restriction.getBaseTypeName().equals(SchemaConstants.XSD_QNAME)) {
 1612                       // we have to process the qname here and shoud find the local part and namespace uri
 1613                       String value = enumeration.getValue().toString();
 1614                       String prefix = value.substring(0, value.indexOf(":"));
 1615                       String localPart = value.substring(value.indexOf(":") + 1);
 1616   
 1617                       String namespaceUri = parentSchema.getNamespaceContext().getNamespaceURI(prefix);
 1618                       // set the string to suite for the convertQname method
 1619                       String qNameString = value + "\", \"" + namespaceUri;
 1620                       metaInfHolder.addEnumFacet(qNameString);
 1621                   } else {
 1622                       metaInfHolder.addEnumFacet(enumeration.getValue().toString());
 1623                   }
 1624   
 1625               }
 1626   
 1627               else if (obj instanceof XmlSchemaLengthFacet) {
 1628                   XmlSchemaLengthFacet length = (XmlSchemaLengthFacet) obj;
 1629                   metaInfHolder.setLengthFacet(Integer.parseInt(length.getValue().toString()));
 1630               }
 1631   
 1632               else if (obj instanceof XmlSchemaMaxExclusiveFacet) {
 1633                   XmlSchemaMaxExclusiveFacet maxEx = (XmlSchemaMaxExclusiveFacet) obj;
 1634                   metaInfHolder.setMaxExclusiveFacet(maxEx.getValue().toString());
 1635               }
 1636   
 1637               else if (obj instanceof XmlSchemaMinExclusiveFacet) {
 1638                   XmlSchemaMinExclusiveFacet minEx = (XmlSchemaMinExclusiveFacet) obj;
 1639                   metaInfHolder.setMinExclusiveFacet(minEx.getValue().toString());
 1640               }
 1641   
 1642               else if (obj instanceof XmlSchemaMaxInclusiveFacet) {
 1643                   XmlSchemaMaxInclusiveFacet maxIn = (XmlSchemaMaxInclusiveFacet) obj;
 1644                   metaInfHolder.setMaxInclusiveFacet(maxIn.getValue().toString());
 1645               }
 1646   
 1647               else if (obj instanceof XmlSchemaMinInclusiveFacet) {
 1648                   XmlSchemaMinInclusiveFacet minIn = (XmlSchemaMinInclusiveFacet) obj;
 1649                   metaInfHolder.setMinInclusiveFacet(minIn.getValue().toString());
 1650               }
 1651   
 1652               else if (obj instanceof XmlSchemaMaxLengthFacet) {
 1653                   XmlSchemaMaxLengthFacet maxLen = (XmlSchemaMaxLengthFacet) obj;
 1654                   metaInfHolder.setMaxLengthFacet(Integer.parseInt(maxLen.getValue().toString()));
 1655               }
 1656   
 1657               else if (obj instanceof XmlSchemaMinLengthFacet) {
 1658                   XmlSchemaMinLengthFacet minLen = (XmlSchemaMinLengthFacet) obj;
 1659                   metaInfHolder.setMinLengthFacet(Integer.parseInt(minLen.getValue().toString()));
 1660               }
 1661           }
 1662       }
 1663   
 1664       /**
 1665        * Handle any attribute
 1666        *
 1667        * @param metainf
 1668        */
 1669       private void processAnyAttribute(BeanWriterMetaInfoHolder metainf, XmlSchemaAnyAttribute anyAtt) {
 1670   
 1671           //The best thing we can do here is to add a set of OMAttributes
 1672           //since attributes do not have the notion of minoccurs/maxoccurs the
 1673           //safest option here is to have an OMAttribute array
 1674           QName qName = new QName(EXTRA_ATTRIBUTE_FIELD_NAME);
 1675           metainf.registerMapping(qName,
 1676                   null,
 1677                   writer.getDefaultAttribArrayClassName(),//always generate an array of
 1678                   //OMAttributes
 1679                   SchemaConstants.ANY_TYPE);
 1680           metainf.addtStatus(qName, SchemaConstants.ATTRIBUTE_TYPE);
 1681           metainf.addtStatus(qName, SchemaConstants.ARRAY_TYPE);
 1682   
 1683       }
 1684   
 1685   
 1686       /**
 1687        * Process the attribute
 1688        *
 1689        * @param att
 1690        * @param metainf
 1691        */
 1692       public void processAttribute(XmlSchemaAttribute att, BeanWriterMetaInfoHolder metainf, XmlSchema parentSchema)
 1693               throws SchemaCompilationException {
 1694   
 1695           QName schemaTypeName = att.getSchemaTypeName();
 1696           if (schemaTypeName != null) {
 1697               if (att.getQName() != null) {
 1698                   if (baseSchemaTypeMap.containsKey(schemaTypeName)) {
 1699   
 1700                       metainf.registerMapping(att.getQName(), schemaTypeName,
 1701                               baseSchemaTypeMap.get(schemaTypeName).toString(), SchemaConstants.ATTRIBUTE_TYPE);
 1702   
 1703                       // add optional attribute status if set
 1704                       String use = att.getUse().getValue();
 1705                       if (USE_NONE.equals(use) || USE_OPTIONAL.equals(use)) {
 1706                           metainf.addtStatus(att.getQName(), SchemaConstants.OPTIONAL_TYPE);
 1707                       }
 1708   
 1709                       String className = findClassName(schemaTypeName, false);
 1710   
 1711                       att.addMetaInfo(
 1712                               SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
 1713                               className);
 1714                       // set the default value
 1715                       if (att.getDefaultValue() != null){
 1716                           metainf.registerDefaultValue(att.getQName(),att.getDefaultValue());
 1717                       }
 1718                       // after
 1719                   } else {
 1720                       XmlSchema resolvedSchema = getParentSchema(parentSchema,schemaTypeName,COMPONENT_TYPE);
 1721                       if (resolvedSchema == null) {
 1722                           throw new SchemaCompilationException("can not find the type " + schemaTypeName +
 1723                                   " from the parent schema " + parentSchema.getTargetNamespace());
 1724                       } else {
 1725                           XmlSchemaType type = resolvedSchema.getTypeByName(schemaTypeName);
 1726                           if (type instanceof XmlSchemaSimpleType) {
 1727                               XmlSchemaSimpleType simpleType = (XmlSchemaSimpleType) type;
 1728   
 1729                               if (simpleType != null) {
 1730                                   if (!isAlreadyProcessed(schemaTypeName)) {
 1731                                       //process simple type
 1732                                       processSimpleSchemaType(simpleType, null, resolvedSchema, null);
 1733                                   }
 1734                                   metainf.registerMapping(att.getQName(),
 1735                                           schemaTypeName,
 1736                                           processedTypemap.get(schemaTypeName).toString(),
 1737                                           SchemaConstants.ATTRIBUTE_TYPE);
 1738                                   // add optional attribute status if set
 1739                                   String use = att.getUse().getValue();
 1740                                   if (USE_NONE.equals(use) || USE_OPTIONAL.equals(use)) {
 1741                                       metainf.addtStatus(att.getQName(), SchemaConstants.OPTIONAL_TYPE);
 1742                                   }
 1743                               }
 1744   
 1745                           }
 1746                       }
 1747                   }
 1748               } else {
 1749                   // this attribute has a type but does not have a name, seems to be invalid
 1750               }
 1751   
 1752           } else if (att.getRefName() != null) {
 1753   
 1754               XmlSchema resolvedSchema = getParentSchema(parentSchema,att.getRefName(),COMPONENT_ATTRIBUTE);
 1755               if (resolvedSchema == null){
 1756                   throw new SchemaCompilationException("can not find the attribute " + att.getRefName() +
 1757                   " from the parent schema " + parentSchema.getTargetNamespace());
 1758               } else {
 1759                   XmlSchemaAttribute xmlSchemaAttribute =
 1760                           (XmlSchemaAttribute) resolvedSchema.getAttributes().getItem(att.getRefName());
 1761                   if (xmlSchemaAttribute != null) {
 1762                       // call recursively to process the schema
 1763                       processAttribute(xmlSchemaAttribute, metainf, resolvedSchema);
 1764                   } else {
 1765                       throw new SchemaCompilationException("Attribute QName reference refer to an invalid attribute " +
 1766                               att.getRefName());
 1767                   }
 1768               }
 1769   
 1770           } else {
 1771               // this attribute refers to a custom type, probably one of the extended simple types.
 1772               // with the inline schema definition
 1773               QName attributeQName = att.getQName();
 1774               if (attributeQName != null) {
 1775                   XmlSchemaSimpleType attributeSimpleType = att.getSchemaType();
 1776                   XmlSchema resolvedSchema = parentSchema;
 1777                   if (attributeSimpleType == null) {
 1778                       // try to get the schema for using qname
 1779                       QName attributeSchemaQname = att.getSchemaTypeName();
 1780                       if (attributeSchemaQname != null) {
 1781                           resolvedSchema = getParentSchema(parentSchema,attributeSchemaQname,COMPONENT_TYPE);
 1782                           if (resolvedSchema == null){
 1783                               throw new SchemaCompilationException("can not find the type " + attributeSchemaQname
 1784                                 + " from the parent schema " + parentSchema.getTargetNamespace());
 1785                           } else {
 1786                               attributeSimpleType = (XmlSchemaSimpleType)
 1787                                       resolvedSchema.getTypeByName(attributeSchemaQname);
 1788                           }
 1789                       }
 1790                   }
 1791   
 1792                   if (attributeSimpleType != null) {
 1793                       QName schemaTypeQName = att.getSchemaTypeName();
 1794                       if (schemaTypeQName == null) {
 1795                           // set the parent schema target name space since attribute Qname uri is ""
 1796                           if (attributeSimpleType.getQName() != null) {
 1797                               schemaTypeQName = attributeSimpleType.getQName();
 1798                           } else {
 1799                               schemaTypeQName = new QName(parentSchema.getTargetNamespace(),
 1800                                       attributeQName.getLocalPart() + getNextTypeSuffix(attributeQName.getLocalPart()));
 1801   
 1802                           }
 1803                       }
 1804                       if (!isAlreadyProcessed(schemaTypeQName)){
 1805                           // we have to process only if it has not processed
 1806                           processSimpleSchemaType(attributeSimpleType, null, resolvedSchema, schemaTypeQName);
 1807                       }
 1808                       metainf.registerMapping(att.getQName(),
 1809                               schemaTypeQName,
 1810                               processedTypemap.get(schemaTypeQName).toString(),
 1811                               SchemaConstants.ATTRIBUTE_TYPE);
 1812                       // add optional attribute status if set
 1813                       String use = att.getUse().getValue();
 1814                       if (USE_NONE.equals(use) || USE_OPTIONAL.equals(use)) {
 1815                           metainf.addtStatus(att.getQName(), SchemaConstants.OPTIONAL_TYPE);
 1816                       }
 1817                   } else {
 1818                       // TODO: handle the case when no attribute type specifed
 1819                       log.warn("No attribute type has defined to the Attribute " + attributeQName);
 1820                   }
 1821   
 1822               } else {
 1823                   throw new SchemaCompilationException("Attribute QName reference refer to an invalid attribute " +
 1824                           attributeQName);
 1825               }
 1826   
 1827           }
 1828       }
 1829   
 1830       /**
 1831        * Process a particle- A particle may be a sequence,all or a choice
 1832        * @param parentElementQName - this can either be parent element QName or parent Complex type qname
 1833        * @param particle - particle being processed
 1834        * @param metainfHolder -
 1835        * @param parentSchema
 1836        * @throws SchemaCompilationException
 1837        */
 1838       private void processParticle(QName parentElementQName,
 1839                                    XmlSchemaParticle particle,
 1840                                    BeanWriterMetaInfoHolder metainfHolder
 1841               , XmlSchema parentSchema) throws SchemaCompilationException {
 1842   
 1843           if (particle instanceof XmlSchemaSequence) {
 1844               XmlSchemaSequence xmlSchemaSequence = (XmlSchemaSequence) particle;
 1845   
 1846               XmlSchemaObjectCollection items = xmlSchemaSequence.getItems();
 1847               if ((xmlSchemaSequence.getMaxOccurs() > 1) && (parentElementQName != null)) {
 1848                   // we have to process many sequence types
 1849                   BeanWriterMetaInfoHolder beanWriterMetaInfoHolder = new BeanWriterMetaInfoHolder();
 1850                   process(parentElementQName, items, beanWriterMetaInfoHolder, true, parentSchema);
 1851                   beanWriterMetaInfoHolder.setParticleClass(true);
 1852                   QName sequenceQName = new QName(parentElementQName.getNamespaceURI(),
 1853                            parentElementQName.getLocalPart() + "Sequence");
 1854                   String javaClassName = writeComplexParticle(sequenceQName,beanWriterMetaInfoHolder);
 1855                   processedTypemap.put(sequenceQName, javaClassName);
 1856   
 1857                   // add this as an array to the original class
 1858                   metainfHolder.registerMapping(sequenceQName,
 1859                           sequenceQName,
 1860                           findClassName(sequenceQName,true),
 1861                           SchemaConstants.ARRAY_TYPE);
 1862                   metainfHolder.setOrdered(true);
 1863                   metainfHolder.registerQNameIndex(sequenceQName,metainfHolder.getOrderStartPoint() + 1);
 1864                   metainfHolder.setHasParticleType(true);
 1865                   metainfHolder.addtStatus(sequenceQName,SchemaConstants.PARTICLE_TYPE_ELEMENT);
 1866                   metainfHolder.addMaxOccurs(sequenceQName,xmlSchemaSequence.getMaxOccurs());
 1867                   metainfHolder.addMinOccurs(sequenceQName,xmlSchemaSequence.getMinOccurs());
 1868   
 1869   
 1870               } else {
 1871                   if (options.isBackwordCompatibilityMode()) {
 1872                       process(parentElementQName,items, metainfHolder, false, parentSchema);
 1873                   } else {
 1874                       process(parentElementQName,items, metainfHolder, true, parentSchema);
 1875                   }
 1876               }
 1877   
 1878           } else if (particle instanceof XmlSchemaAll) {
 1879               XmlSchemaObjectCollection items = ((XmlSchemaAll) particle).getItems();
 1880               process(parentElementQName,items, metainfHolder, false, parentSchema);
 1881           } else if (particle instanceof XmlSchemaChoice) {
 1882               XmlSchemaChoice xmlSchemaChoice = (XmlSchemaChoice) particle;
 1883               XmlSchemaObjectCollection items = ((XmlSchemaChoice) particle).getItems();
 1884   
 1885               if ((xmlSchemaChoice.getMaxOccurs() > 1)) {
 1886                   // we have to process many sequence types
 1887                   BeanWriterMetaInfoHolder beanWriterMetaInfoHolder = new BeanWriterMetaInfoHolder();
 1888                   beanWriterMetaInfoHolder.setChoice(true);
 1889                   process(parentElementQName,items, beanWriterMetaInfoHolder, false, parentSchema);
 1890                   beanWriterMetaInfoHolder.setParticleClass(true);
 1891                   QName choiceQName = new QName(parentElementQName.getNamespaceURI(),
 1892                            parentElementQName.getLocalPart() + "Choice");
 1893                   String javaClassName = writeComplexParticle(choiceQName,beanWriterMetaInfoHolder);
 1894                   processedTypemap.put(choiceQName, javaClassName);
 1895   
 1896                   // add this as an array to the original class
 1897                   metainfHolder.registerMapping(choiceQName,
 1898                           choiceQName,
 1899                           findClassName(choiceQName,true),
 1900                           SchemaConstants.ARRAY_TYPE);
 1901                   metainfHolder.setOrdered(true);
 1902                   metainfHolder.setHasParticleType(true);
 1903                   metainfHolder.registerQNameIndex(choiceQName,metainfHolder.getOrderStartPoint() + 1);
 1904                   metainfHolder.addtStatus(choiceQName,SchemaConstants.PARTICLE_TYPE_ELEMENT);
 1905                   metainfHolder.addMaxOccurs(choiceQName,xmlSchemaChoice.getMaxOccurs());
 1906                   metainfHolder.addMinOccurs(choiceQName,xmlSchemaChoice.getMinOccurs());
 1907   
 1908               } else {
 1909                   metainfHolder.setChoice(true);
 1910                   process(parentElementQName,items, metainfHolder, false, parentSchema);
 1911               }
 1912   
 1913   
 1914           } else if (particle instanceof XmlSchemaGroupRef){
 1915   
 1916               XmlSchemaGroupRef xmlSchemaGroupRef = (XmlSchemaGroupRef) particle;
 1917               QName groupQName = xmlSchemaGroupRef.getRefName();
 1918               if (groupQName != null) {
 1919                   if (!processedGroupTypeMap.containsKey(groupQName)) {
 1920                       // processe the schema here
 1921                       XmlSchema resolvedParentSchema = getParentSchema(parentSchema,groupQName,COMPONENT_GROUP);
 1922                       if (resolvedParentSchema == null){
 1923                           throw new SchemaCompilationException("can not find the group " + groupQName
 1924                            + " from the parent schema " + parentSchema.getTargetNamespace());
 1925                       } else {
 1926                           XmlSchemaGroup xmlSchemaGroup = (XmlSchemaGroup)
 1927                                   resolvedParentSchema.getGroups().getItem(groupQName);
 1928                           processGroup(xmlSchemaGroup, groupQName, resolvedParentSchema);
 1929                       }
 1930                   }
 1931               } else {
 1932                   throw new SchemaCompilationException("Referenced name is null");
 1933               }
 1934               boolean isArray = xmlSchemaGroupRef.getMaxOccurs() > 1;
 1935   
 1936               // add this as an array to the original class
 1937               String groupClassName = (String) processedGroupTypeMap.get(groupQName);
 1938               if (isArray){
 1939                   groupClassName = groupClassName + "[]";
 1940               }
 1941               metainfHolder.registerMapping(groupQName, groupQName, groupClassName);
 1942               if (isArray) {
 1943                   metainfHolder.addtStatus(groupQName, SchemaConstants.ARRAY_TYPE);
 1944               }
 1945               metainfHolder.addtStatus(groupQName, SchemaConstants.PARTICLE_TYPE_ELEMENT);
 1946               metainfHolder.addMaxOccurs(groupQName, xmlSchemaGroupRef.getMaxOccurs());
 1947               metainfHolder.addMinOccurs(groupQName, xmlSchemaGroupRef.getMinOccurs());
 1948               metainfHolder.setHasParticleType(true);
 1949               metainfHolder.setOrdered(true);
 1950               metainfHolder.registerQNameIndex(groupQName,metainfHolder.getOrderStartPoint() + 1);
 1951   
 1952           }
 1953       }
 1954   
 1955       /**
 1956        *
 1957        * @param parentElementQName - this could either be the complex type parentElementQName or element parentElementQName
 1958        * @param items
 1959        * @param metainfHolder
 1960        * @param order
 1961        * @param parentSchema
 1962        * @throws SchemaCompilationException
 1963        */
 1964       private void process(QName parentElementQName,
 1965                            XmlSchemaObjectCollection items,
 1966                            BeanWriterMetaInfoHolder metainfHolder,
 1967                            boolean order,
 1968                            XmlSchema parentSchema) throws SchemaCompilationException {
 1969           int count = items.getCount();
 1970           Map processedElementArrayStatusMap = new LinkedHashMap();
 1971           Map processedElementTypeMap = new LinkedHashMap();
 1972           List localNillableList = new ArrayList();
 1973   
 1974           Map particleQNameMap = new HashMap();
 1975   
 1976           // this list is used to keep the details of the
 1977           // elements within a choice withing sequence
 1978           List innerChoiceElementList = new ArrayList();
 1979   
 1980           Map elementOrderMap = new HashMap();
 1981   
 1982           int sequenceCounter = 0;
 1983           for (int i = 0; i < count; i++) {
 1984               XmlSchemaObject item = items.getItem(i);
 1985   
 1986               if (item instanceof XmlSchemaElement) {
 1987                   //recursively process the element
 1988                   XmlSchemaElement xsElt = (XmlSchemaElement) item;
 1989   
 1990                   boolean isArray = isArray(xsElt);
 1991                   processElement(xsElt, processedElementTypeMap, localNillableList, parentSchema); //we know for sure this is not an outer type
 1992                   processedElementArrayStatusMap.put(xsElt, (isArray) ? Boolean.TRUE : Boolean.FALSE);
 1993                   if (order) {
 1994                       //we need to keep the order of the elements. So push the elements to another
 1995                       //hashmap with the order number
 1996                       elementOrderMap.put(xsElt, new Integer(sequenceCounter));
 1997                   }
 1998   
 1999                   //handle xsd:any ! We place an OMElement (or an array of OMElements) in the generated class
 2000               } else if (item instanceof XmlSchemaAny) {
 2001                   XmlSchemaAny any = (XmlSchemaAny) item;
 2002                   processedElementTypeMap.put(new QName(ANY_ELEMENT_FIELD_NAME), any);
 2003                   //any can also be inside a sequence
 2004                   if (order) {
 2005                       elementOrderMap.put(any, new Integer(sequenceCounter));
 2006                   }
 2007                   //we do not register the array status for the any type
 2008                   processedElementArrayStatusMap.put(any, isArray(any) ? Boolean.TRUE : Boolean.FALSE);
 2009               } else if (item instanceof XmlSchemaSequence) {
 2010                   // we have to process many sequence types
 2011   
 2012                   XmlSchemaSequence xmlSchemaSequence = (XmlSchemaSequence) item;
 2013                   if (xmlSchemaSequence.getItems().getCount() > 0) {
 2014                       BeanWriterMetaInfoHolder beanWriterMetaInfoHolder = new BeanWriterMetaInfoHolder();
 2015                       process(parentElementQName, xmlSchemaSequence.getItems(), beanWriterMetaInfoHolder, true, parentSchema);
 2016                       beanWriterMetaInfoHolder.setParticleClass(true);
 2017                       String localName = parentElementQName.getLocalPart() + "Sequence";
 2018                       QName sequenceQName = new QName(parentElementQName.getNamespaceURI(),
 2019                               localName + getNextTypeSuffix(localName));
 2020                       String javaClassName = writeComplexParticle(sequenceQName, beanWriterMetaInfoHolder);
 2021                       processedTypemap.put(sequenceQName, javaClassName);
 2022   
 2023                       //put the partical to array
 2024                       Boolean isArray = xmlSchemaSequence.getMaxOccurs() > 1 ? Boolean.TRUE : Boolean.FALSE;
 2025                       processedElementArrayStatusMap.put(item, isArray);
 2026                       particleQNameMap.put(item, sequenceQName);
 2027   
 2028                       if (order) {
 2029                           elementOrderMap.put(item, new Integer(sequenceCounter));
 2030                       }
 2031                   }
 2032   
 2033               } else if (item instanceof XmlSchemaChoice) {
 2034                   // we have to process many sequence types
 2035   
 2036                   XmlSchemaChoice xmlSchemaChoice = (XmlSchemaChoice) item;
 2037                   if (xmlSchemaChoice.getItems().getCount() > 0) {
 2038                       BeanWriterMetaInfoHolder beanWriterMetaInfoHolder = new BeanWriterMetaInfoHolder();
 2039                       beanWriterMetaInfoHolder.setChoice(true);
 2040                       process(parentElementQName, xmlSchemaChoice.getItems(), beanWriterMetaInfoHolder, false, parentSchema);
 2041                       beanWriterMetaInfoHolder.setParticleClass(true);
 2042                       String localName = parentElementQName.getLocalPart() + "Choice";
 2043                       QName choiceQName = new QName(parentElementQName.getNamespaceURI(),
 2044                               localName + getNextTypeSuffix(localName));
 2045                       String javaClassName = writeComplexParticle(choiceQName, beanWriterMetaInfoHolder);
 2046                       processedTypemap.put(choiceQName, javaClassName);
 2047   
 2048                       //put the partical to array
 2049                       Boolean isArray = xmlSchemaChoice.getMaxOccurs() > 1 ? Boolean.TRUE : Boolean.FALSE;
 2050                       processedElementArrayStatusMap.put(item, isArray);
 2051                       particleQNameMap.put(item, choiceQName);
 2052   
 2053                       if (order) {
 2054                           elementOrderMap.put(item, new Integer(sequenceCounter));
 2055                       }
 2056                   }
 2057   
 2058               } else if (item instanceof XmlSchemaGroupRef) {
 2059   
 2060                   XmlSchemaGroupRef xmlSchemaGroupRef = (XmlSchemaGroupRef) item;
 2061                   QName groupQName = xmlSchemaGroupRef.getRefName();
 2062                   if (groupQName != null){
 2063                       if (!processedGroupTypeMap.containsKey(groupQName)){
 2064                           // processe the schema here
 2065                           XmlSchema resolvedParentSchema = getParentSchema(parentSchema,groupQName,COMPONENT_GROUP);
 2066                           if (resolvedParentSchema == null){
 2067                               throw new SchemaCompilationException("Can not find the group with the qname" +
 2068                                       groupQName + " from the parent schema " + parentSchema.getTargetNamespace());
 2069                           } else {
 2070                               XmlSchemaGroup xmlSchemaGroup =
 2071                                       (XmlSchemaGroup) resolvedParentSchema.getGroups().getItem(groupQName);
 2072                               if (xmlSchemaGroup != null){
 2073                                   processGroup(xmlSchemaGroup, groupQName, resolvedParentSchema);
 2074                               }
 2075                           }
 2076                       }
 2077   
 2078                       Boolean isArray = xmlSchemaGroupRef.getMaxOccurs() > 1 ? Boolean.TRUE : Boolean.FALSE;
 2079                       processedElementArrayStatusMap.put(item,isArray);
 2080                       particleQNameMap.put(item,groupQName);
 2081   
 2082                       if (order){
 2083                           elementOrderMap.put(item, new Integer(sequenceCounter));
 2084                       }
 2085   
 2086                   } else {
 2087                       throw new SchemaCompilationException("Referenced name is null");
 2088                   }
 2089               } else {
 2090                   //there may be other types to be handled here. Add them
 2091                   //when we are ready
 2092               }
 2093             sequenceCounter++;
 2094           }
 2095   
 2096           // loop through the processed items and add them to the matainf object
 2097           Iterator processedElementsIterator = processedElementArrayStatusMap.keySet().iterator();
 2098           int startingItemNumberOrder = metainfHolder.getOrderStartPoint();
 2099           while (processedElementsIterator.hasNext()) {
 2100               Object child = processedElementsIterator.next();
 2101   
 2102               // process the XmlSchemaElement
 2103               if (child instanceof XmlSchemaElement) {
 2104                   XmlSchemaElement elt = (XmlSchemaElement) child;
 2105                   QName referencedQName = null;
 2106   
 2107   
 2108                   if (elt.getQName() != null) {
 2109                       referencedQName = elt.getQName();
 2110                       QName schemaTypeQName = elt.getSchemaType() != null ? elt.getSchemaType().getQName() : elt.getSchemaTypeName();
 2111                       if (schemaTypeQName != null) {
 2112                           String clazzName = (String) processedElementTypeMap.get(elt.getQName());
 2113                           metainfHolder.registerMapping(referencedQName,
 2114                                   schemaTypeQName,
 2115                                   clazzName,
 2116                                   ((Boolean) processedElementArrayStatusMap.get(elt)).booleanValue() ?
 2117                                           SchemaConstants.ARRAY_TYPE :
 2118                                           SchemaConstants.ELEMENT_TYPE);
 2119                           if (innerChoiceElementList.contains(referencedQName)){
 2120                               metainfHolder.addtStatus(referencedQName,SchemaConstants.INNER_CHOICE_ELEMENT);
 2121                           }
 2122                           // register the default value as well
 2123                           if (elt.getDefaultValue() != null){
 2124                              metainfHolder.registerDefaultValue(referencedQName,elt.getDefaultValue());
 2125                           }
 2126   
 2127                       }
 2128                   }
 2129   
 2130                   if (elt.getRefName() != null) { //probably this is referenced
 2131                       referencedQName = elt.getRefName();
 2132                       boolean arrayStatus = ((Boolean) processedElementArrayStatusMap.get(elt)).booleanValue();
 2133                       String clazzName = findRefClassName(referencedQName, arrayStatus);
 2134                       if (clazzName == null) {
 2135                           clazzName = findClassName(referencedQName, arrayStatus);
 2136                       }
 2137                       XmlSchema resolvedParentSchema = getParentSchema(parentSchema,referencedQName,COMPONENT_ELEMENT);
 2138                       if (resolvedParentSchema == null) {
 2139                           throw new SchemaCompilationException("Can not find the element " + referencedQName +
 2140                                   " from the parent schema " + parentSchema.getTargetNamespace());
 2141                       } else {
 2142                           XmlSchemaElement refElement = resolvedParentSchema.getElementByName(referencedQName);
 2143   
 2144                           // register the mapping if we found the referenced element
 2145                           // else throw an exception
 2146                           if (refElement != null) {
 2147                               metainfHolder.registerMapping(referencedQName,
 2148                                       refElement.getSchemaTypeName()
 2149                                       , clazzName,
 2150                                       arrayStatus ?
 2151                                               SchemaConstants.ARRAY_TYPE :
 2152                                               SchemaConstants.ELEMENT_TYPE);
 2153                           } else {
 2154                               if (referencedQName.equals(SchemaConstants.XSD_SCHEMA)) {
 2155                                   metainfHolder.registerMapping(referencedQName,
 2156                                           null,
 2157                                           writer.getDefaultClassName(),
 2158                                           SchemaConstants.ANY_TYPE);
 2159                               } else {
 2160                                   throw new SchemaCompilationException(SchemaCompilerMessages.getMessage("schema.referencedElementNotFound", referencedQName.toString()));
 2161                               }
 2162                           }
 2163                       }
 2164                   }
 2165   
 2166                   if (referencedQName == null) {
 2167                       throw new SchemaCompilationException(SchemaCompilerMessages.getMessage("schema.emptyName"));
 2168                   }
 2169   
 2170                   //register the occurence counts
 2171                   metainfHolder.addMaxOccurs(referencedQName, elt.getMaxOccurs());
 2172                   // if the strict validation off then we consider all elements have minOccurs zero on it
 2173                   if (this.options.isOffStrictValidation()){
 2174                       metainfHolder.addMinOccurs(referencedQName, 0);
 2175                   } else {
 2176                       metainfHolder.addMinOccurs(referencedQName, elt.getMinOccurs());
 2177                   }
 2178                   //we need the order to be preserved. So record the order also
 2179                   if (order) {
 2180                       //record the order in the metainf holder
 2181                       Integer integer = (Integer) elementOrderMap.get(elt);
 2182                       metainfHolder.registerQNameIndex(referencedQName,
 2183                               startingItemNumberOrder + integer.intValue());
 2184                   }
 2185   
 2186                   //get the nillable state and register that on the metainf holder
 2187                   if (localNillableList.contains(elt.getQName())) {
 2188                       metainfHolder.registerNillableQName(elt.getQName());
 2189                   }
 2190   
 2191                   //get the binary state and add that to the status map
 2192                   if (isBinary(elt)) {
 2193                       metainfHolder.addtStatus(elt.getQName(),
 2194                               SchemaConstants.BINARY_TYPE);
 2195                   }
 2196                   // process the XMLSchemaAny
 2197               } else if (child instanceof XmlSchemaAny) {
 2198                   XmlSchemaAny any = (XmlSchemaAny) child;
 2199   
 2200                   //since there is only one element here it does not matter
 2201                   //for the constant. However the problem occurs if the users
 2202                   //uses the same name for an element decalration
 2203                   QName anyElementFieldName = new QName(ANY_ELEMENT_FIELD_NAME);
 2204   
 2205                   //this can be an array or a single element
 2206                   boolean isArray = ((Boolean) processedElementArrayStatusMap.get(any)).booleanValue();
 2207                   metainfHolder.registerMapping(anyElementFieldName,
 2208                           null,
 2209                           isArray ? writer.getDefaultClassArrayName() : writer.getDefaultClassName(),
 2210                           SchemaConstants.ANY_TYPE);
 2211                   //if it's an array register an extra status flag with the system
 2212                   if (isArray) {
 2213                       metainfHolder.addtStatus(anyElementFieldName,
 2214                               SchemaConstants.ARRAY_TYPE);
 2215                   }
 2216                   metainfHolder.addMaxOccurs(anyElementFieldName, any.getMaxOccurs());
 2217                   metainfHolder.addMinOccurs(anyElementFieldName, any.getMinOccurs());
 2218   
 2219                   if (order) {
 2220                       //record the order in the metainf holder for the any
 2221                       Integer integer = (Integer) elementOrderMap.get(any);
 2222                       metainfHolder.registerQNameIndex(anyElementFieldName,
 2223                               startingItemNumberOrder + integer.intValue());
 2224                   }
 2225               } else if (child instanceof XmlSchemaSequence) {
 2226                   XmlSchemaSequence xmlSchemaSequence = (XmlSchemaSequence) child;
 2227                   QName sequenceQName = (QName) particleQNameMap.get(child);
 2228                   boolean isArray = xmlSchemaSequence.getMaxOccurs() > 1;
 2229   
 2230                   // add this as an array to the original class
 2231                   metainfHolder.registerMapping(sequenceQName,
 2232                           sequenceQName,
 2233                           findClassName(sequenceQName, isArray));
 2234                   if (isArray) {
 2235                       metainfHolder.addtStatus(sequenceQName, SchemaConstants.ARRAY_TYPE);
 2236                   }
 2237                   metainfHolder.addtStatus(sequenceQName, SchemaConstants.PARTICLE_TYPE_ELEMENT);
 2238                   metainfHolder.addMaxOccurs(sequenceQName, xmlSchemaSequence.getMaxOccurs());
 2239                   metainfHolder.addMinOccurs(sequenceQName, xmlSchemaSequence.getMinOccurs());
 2240                   metainfHolder.setHasParticleType(true);
 2241   
 2242                   if (order) {
 2243                       //record the order in the metainf holder for the any
 2244                       Integer integer = (Integer) elementOrderMap.get(child);
 2245                       metainfHolder.registerQNameIndex(sequenceQName,
 2246                               startingItemNumberOrder + integer.intValue());
 2247                   }
 2248               } else if (child instanceof XmlSchemaChoice) {
 2249                   XmlSchemaChoice xmlSchemaChoice = (XmlSchemaChoice) child;
 2250                   QName choiceQName = (QName) particleQNameMap.get(child);
 2251                   boolean isArray = xmlSchemaChoice.getMaxOccurs() > 1;
 2252   
 2253                   // add this as an array to the original class
 2254                   metainfHolder.registerMapping(choiceQName,
 2255                           choiceQName,
 2256                           findClassName(choiceQName, isArray));
 2257                   if (isArray) {
 2258                       metainfHolder.addtStatus(choiceQName, SchemaConstants.ARRAY_TYPE);
 2259                   }
 2260                   metainfHolder.addtStatus(choiceQName, SchemaConstants.PARTICLE_TYPE_ELEMENT);
 2261                   metainfHolder.addMaxOccurs(choiceQName, xmlSchemaChoice.getMaxOccurs());
 2262                   metainfHolder.addMinOccurs(choiceQName, xmlSchemaChoice.getMinOccurs());
 2263                   metainfHolder.setHasParticleType(true);
 2264   
 2265                   if (order) {
 2266                       //record the order in the metainf holder for the any
 2267                       Integer integer = (Integer) elementOrderMap.get(child);
 2268                       metainfHolder.registerQNameIndex(choiceQName,
 2269                               startingItemNumberOrder + integer.intValue());
 2270                   }
 2271               } else if (child instanceof XmlSchemaGroupRef) {
 2272                   XmlSchemaGroupRef xmlSchemaGroupRef = (XmlSchemaGroupRef) child;
 2273                   QName groupQName = (QName) particleQNameMap.get(child);
 2274                   boolean isArray = xmlSchemaGroupRef.getMaxOccurs() > 1;
 2275   
 2276                   // add this as an array to the original class
 2277                   String groupClassName = (String) processedGroupTypeMap.get(groupQName);
 2278                   if (isArray){
 2279                       groupClassName = groupClassName + "[]";
 2280                   }
 2281                   metainfHolder.registerMapping(groupQName,
 2282                           groupQName,
 2283                           groupClassName);
 2284                   if (isArray) {
 2285                       metainfHolder.addtStatus(groupQName, SchemaConstants.ARRAY_TYPE);
 2286                   }
 2287                   metainfHolder.addtStatus(groupQName, SchemaConstants.PARTICLE_TYPE_ELEMENT);
 2288                   metainfHolder.addMaxOccurs(groupQName, xmlSchemaGroupRef.getMaxOccurs());
 2289                   metainfHolder.addMinOccurs(groupQName, xmlSchemaGroupRef.getMinOccurs());
 2290                   metainfHolder.setHasParticleType(true);
 2291   
 2292                   if (order) {
 2293                       //record the order in the metainf holder for the any
 2294                       Integer integer = (Integer) elementOrderMap.get(child);
 2295                       metainfHolder.registerQNameIndex(groupQName,
 2296                               startingItemNumberOrder + integer.intValue());
 2297                   }
 2298               }
 2299           }
 2300   
 2301           //set the ordered flag in the metainf holder
 2302           metainfHolder.setOrdered(order);
 2303       }
 2304   
 2305       /**
 2306        *
 2307        * @param xmlSchemaGroup
 2308        * @param schemaGroupQName- we have to pass this since xml schema does not provide
 2309        * this properly
 2310        * @param parentSchema
 2311        * @throws SchemaCompilationException
 2312        */
 2313   
 2314       private void processGroup(XmlSchemaGroup xmlSchemaGroup,
 2315                                 QName schemaGroupQName,
 2316                                 XmlSchema parentSchema) throws SchemaCompilationException {
 2317   
 2318           // find the group base item
 2319           XmlSchemaGroupBase xmlSchemaGroupBase = xmlSchemaGroup.getParticle();
 2320           if (xmlSchemaGroupBase != null){
 2321               if (xmlSchemaGroupBase instanceof XmlSchemaSequence){
 2322                   XmlSchemaSequence xmlSchemaSequence = (XmlSchemaSequence) xmlSchemaGroupBase;
 2323                   if (xmlSchemaSequence.getItems().getCount() > 0) {
 2324                       BeanWriterMetaInfoHolder beanWriterMetaInfoHolder = new BeanWriterMetaInfoHolder();
 2325                       process(schemaGroupQName, xmlSchemaSequence.getItems(), beanWriterMetaInfoHolder, true, parentSchema);
 2326                       beanWriterMetaInfoHolder.setParticleClass(true);
 2327                       String javaClassName = writeComplexParticle(schemaGroupQName, beanWriterMetaInfoHolder);
 2328                       processedGroupTypeMap.put(schemaGroupQName, javaClassName);
 2329   //                    processedTypemap.put(schemaGroupQName, javaClassName);
 2330                   }
 2331   
 2332               } else if (xmlSchemaGroupBase instanceof XmlSchemaChoice){
 2333                   XmlSchemaChoice xmlSchemaChoice = (XmlSchemaChoice) xmlSchemaGroupBase;
 2334                   if (xmlSchemaChoice.getItems().getCount() > 0) {
 2335                       BeanWriterMetaInfoHolder beanWriterMetaInfoHolder = new BeanWriterMetaInfoHolder();
 2336                       beanWriterMetaInfoHolder.setChoice(true);
 2337                       process(schemaGroupQName, xmlSchemaChoice.getItems(), beanWriterMetaInfoHolder, false, parentSchema);
 2338                       beanWriterMetaInfoHolder.setParticleClass(true);
 2339                       String javaClassName = writeComplexParticle(schemaGroupQName, beanWriterMetaInfoHolder);
 2340                       processedGroupTypeMap.put(schemaGroupQName, javaClassName);
 2341   //                    processedTypemap.put(schemaGroupQName, javaClassName);
 2342                   }
 2343               }
 2344           }
 2345       }
 2346   
 2347       /**
 2348        * Checks whether a given element is a binary element
 2349        *
 2350        * @param elt
 2351        */
 2352       private boolean isBinary(XmlSchemaElement elt) {
 2353           return elt.getSchemaType() != null &&
 2354                   SchemaConstants.XSD_BASE64.equals(elt.getSchemaType().getQName());
 2355       }
 2356   
 2357       /**
 2358        * Checks whether a given qname is a binary
 2359        *
 2360        * @param qName
 2361        */
 2362       private boolean isBinary(QName qName) {
 2363           return qName != null &&
 2364                   SchemaConstants.XSD_BASE64.equals(qName);
 2365       }
 2366   
 2367       /**
 2368        * @param simpleType
 2369        * @param xsElt
 2370        * @param parentSchema
 2371        * @param qname        - fake Qname to use if the xsElt is null.
 2372        * @throws SchemaCompilationException
 2373        */
 2374       private void processSimpleSchemaType(XmlSchemaSimpleType simpleType,
 2375                                            XmlSchemaElement xsElt,
 2376                                            XmlSchema parentSchema,
 2377                                            QName qname) throws SchemaCompilationException {
 2378   
 2379           String fullyQualifiedClassName = null;
 2380           if (simpleType.getQName() != null) {
 2381               if (processedTypemap.containsKey(simpleType.getQName())
 2382                       || baseSchemaTypeMap.containsKey(simpleType.getQName())) {
 2383                   return;
 2384               }
 2385   
 2386               // Must do this up front to support recursive types
 2387               fullyQualifiedClassName = writer.makeFullyQualifiedClassName(simpleType.getQName());
 2388               // we put the qname to processed type map it is only named type
 2389               // otherwise we have to any way process that element.
 2390               processedTypemap.put(simpleType.getQName(), fullyQualifiedClassName);
 2391           } else {
 2392   
 2393               QName fakeQname;
 2394               if (xsElt != null) {
 2395                   fakeQname = new QName(xsElt.getQName().getNamespaceURI(), xsElt.getQName().getLocalPart() + getNextTypeSuffix(xsElt.getQName().getLocalPart()));
 2396                   // we have to set this otherwise the ours attribute would not set properly if refered to this simple
 2397                   // type from any other element
 2398                   xsElt.setSchemaTypeName(fakeQname);
 2399                   changedElementSet.add(xsElt);
 2400   
 2401               } else {
 2402                   fakeQname = qname;
 2403               }
 2404               if (processedTypemap.containsKey(fakeQname)
 2405                       || baseSchemaTypeMap.containsKey(fakeQname)) {
 2406                   return;
 2407               }
 2408               fullyQualifiedClassName = writer.makeFullyQualifiedClassName(fakeQname);
 2409               simpleType.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.FAKE_QNAME, fakeQname);
 2410   
 2411               // should put this to the processedTypemap to generate the code correctly
 2412               processedTypemap.put(fakeQname, fullyQualifiedClassName);
 2413           }
 2414   
 2415           //register that in the schema metainfo bag
 2416           simpleType.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
 2417                   fullyQualifiedClassName);
 2418   
 2419           BeanWriterMetaInfoHolder metaInfHolder = processSimpleType(simpleType, parentSchema);
 2420           metaInfHolder.setSimple(true);
 2421   
 2422           if (simpleType.getQName() == null) {
 2423               this.processedAnonymousComplexTypesMap.put(xsElt, metaInfHolder);
 2424               QName fakeQname;
 2425               if (xsElt != null) {
 2426                   fakeQname = new QName(xsElt.getQName().getNamespaceURI(), xsElt.getQName().getLocalPart());
 2427               } else {
 2428                   fakeQname = qname;
 2429                   simpleType.setName(fakeQname.getLocalPart());
 2430                   changedSimpleTypeSet.add(simpleType);
 2431                   simpleType.setSourceURI(fakeQname.getNamespaceURI());
 2432               }
 2433               simpleTypesMap.put(fakeQname, fullyQualifiedClassName);
 2434           }
 2435           //add this information to the metainfo holder
 2436           metaInfHolder.setOwnQname(simpleType.getQName());
 2437           if (fullyQualifiedClassName != null) {
 2438               metaInfHolder.setOwnClassName(fullyQualifiedClassName);
 2439           }
 2440           //write the class. This type mapping would have been populated right now
 2441           //Note - We always write classes for named complex types
 2442           writeSimpleType(simpleType, metaInfHolder);
 2443       }
 2444   
 2445       private BeanWriterMetaInfoHolder processSimpleType(XmlSchemaSimpleType simpleType, XmlSchema parentSchema) throws SchemaCompilationException {
 2446           BeanWriterMetaInfoHolder metaInfHolder = new BeanWriterMetaInfoHolder();
 2447   
 2448           // handle the restriction
 2449           XmlSchemaSimpleTypeContent content = simpleType.getContent();
 2450           QName parentSimpleTypeQname = simpleType.getQName();
 2451           if (parentSimpleTypeQname == null) {
 2452               parentSimpleTypeQname = (QName) simpleType.getMetaInfoMap().get(SchemaConstants.SchemaCompilerInfoHolder.FAKE_QNAME);
 2453           }
 2454           if (content != null) {
 2455               if (content instanceof XmlSchemaSimpleTypeRestriction) {
 2456                   XmlSchemaSimpleTypeRestriction restriction = (XmlSchemaSimpleTypeRestriction) content;
 2457   
 2458                   QName baseTypeName = restriction.getBaseTypeName();
 2459                   //check whether the base type is one of the base schema types
 2460   
 2461                   if (baseSchemaTypeMap.containsKey(baseTypeName)) {
 2462                       //process restriction base type
 2463   
 2464                       processSimpleRestrictionBaseType(parentSimpleTypeQname, restriction.getBaseTypeName(), metaInfHolder, parentSchema);
 2465                       //process facets
 2466                       if (!SchemaConstants.XSD_BOOLEAN.equals(baseTypeName)){
 2467                           processFacets(restriction, metaInfHolder, parentSchema);
 2468                       }
 2469                   } else {
 2470                       //recurse
 2471                       // this must be a xmlschema bug
 2472                       // it should return the schematype for restriction.getBaseType():
 2473                       XmlSchema resolvedSchema = getParentSchema(parentSchema, baseTypeName, COMPONENT_TYPE);
 2474                       if (resolvedSchema == null) {
 2475                           throw new SchemaCompilationException("can not find the type " + baseTypeName +
 2476                                   " from the parent schema " + parentSchema.getTargetNamespace());
 2477                       } else {
 2478                           XmlSchemaType restrictionBaseType = resolvedSchema.getTypeByName(baseTypeName);
 2479                           if (restrictionBaseType instanceof XmlSchemaSimpleType) {
 2480                               if ((restrictionBaseType != null) && (!isAlreadyProcessed(baseTypeName))) {
 2481                                   processSimpleSchemaType((XmlSchemaSimpleType) restrictionBaseType,
 2482                                           null, resolvedSchema, null);
 2483                               }
 2484                               // process restriction
 2485                               processSimpleRestrictionBaseType(parentSimpleTypeQname,
 2486                                       restriction.getBaseTypeName(), metaInfHolder, resolvedSchema);
 2487                           }
 2488                       }
 2489   
 2490                   }
 2491               } else if (content instanceof XmlSchemaSimpleTypeUnion) {
 2492                   XmlSchemaSimpleTypeUnion simpleTypeUnion = (XmlSchemaSimpleTypeUnion) content;
 2493                   QName[] qnames = simpleTypeUnion.getMemberTypesQNames();
 2494                   if (qnames != null) {
 2495                       QName qname;
 2496                       for (int i = 0; i < qnames.length; i++) {
 2497                           qname = qnames[i];
 2498                           if (baseSchemaTypeMap.containsKey(qname)) {
 2499                               metaInfHolder.addMemberType(qname, (String) baseSchemaTypeMap.get(qname));
 2500                           } else {
 2501                               XmlSchema resolvedSchema = getParentSchema(parentSchema, qname, COMPONENT_TYPE);
 2502                               if (resolvedSchema == null) {
 2503                                   throw new SchemaCompilationException("can not find the type " + qname +
 2504                                           " from the parent schema " + parentSchema.getTargetNamespace());
 2505                               } else {
 2506                                   XmlSchemaType type = resolvedSchema.getTypeByName(qname);
 2507                                   if (type instanceof XmlSchemaSimpleType) {
 2508                                       XmlSchemaSimpleType memberSimpleType = (XmlSchemaSimpleType) type;
 2509                                       if (!isAlreadyProcessed(qname)) {
 2510                                           processSimpleSchemaType(memberSimpleType, null, resolvedSchema, null);
 2511                                       }
 2512                                       metaInfHolder.addMemberType(qname, (String) processedTypemap.get(qname));
 2513                                   } else {
 2514                                       throw new SchemaCompilationException("Unions can not have complex types as a member type");
 2515                                   }
 2516                               }
 2517                           }
 2518                       }
 2519                   } else {
 2520                       XmlSchemaObjectCollection xmlSchemaObjectCollection = simpleTypeUnion.getBaseTypes();
 2521                       XmlSchemaObject xmlSchemaObject;
 2522                       QName childQname;
 2523                       int i = 1;
 2524                       for (Iterator iter = xmlSchemaObjectCollection.getIterator(); iter.hasNext();) {
 2525                           xmlSchemaObject = (XmlSchemaObject) iter.next();
 2526                           i++;
 2527                           if (xmlSchemaObject instanceof XmlSchemaSimpleType) {
 2528                               XmlSchemaSimpleType unionSimpleType = (XmlSchemaSimpleType) xmlSchemaObject;
 2529                               childQname = unionSimpleType.getQName();
 2530                               if (childQname == null) {
 2531                                   // we create a fake Qname for all these simple types since most propably they don't have one
 2532                                   childQname = new QName(parentSimpleTypeQname.getNamespaceURI(), parentSimpleTypeQname.getLocalPart() + getNextTypeSuffix(parentSimpleTypeQname.getLocalPart()));
 2533                               }
 2534                               // this is an inner simple type of the union so it shold not have
 2535                               // processed
 2536                               processSimpleSchemaType(unionSimpleType, null, parentSchema, childQname);
 2537                               metaInfHolder.addMemberType(childQname, (String) processedTypemap.get(childQname));
 2538                           }
 2539   
 2540                       }
 2541                   }
 2542   
 2543                   metaInfHolder.setUnion(true);
 2544   
 2545               } else if (content instanceof XmlSchemaSimpleTypeList) {
 2546                   XmlSchemaSimpleTypeList simpleTypeList = (XmlSchemaSimpleTypeList) content;
 2547                   QName itemTypeQName = simpleTypeList.getItemTypeName();
 2548   
 2549                   if (itemTypeQName != null) {
 2550                       if (!isAlreadyProcessed(itemTypeQName)) {
 2551                           XmlSchema resolvedSchema = getParentSchema(parentSchema, itemTypeQName, COMPONENT_TYPE);
 2552                           if (resolvedSchema == null) {
 2553                               throw new SchemaCompilationException("can not find the type " + itemTypeQName +
 2554                                       " from the parent type " + parentSchema.getTargetNamespace());
 2555                           } else {
 2556                               XmlSchemaType simpleSchemaType = resolvedSchema.getTypeByName(itemTypeQName);
 2557                               if (simpleSchemaType instanceof XmlSchemaSimpleType) {
 2558                                   processSimpleSchemaType((XmlSchemaSimpleType) simpleSchemaType, null, resolvedSchema, null);
 2559                               }
 2560                           }
 2561                       }
 2562                   } else {
 2563                       XmlSchemaSimpleType listSimpleType = simpleTypeList.getItemType();
 2564                       itemTypeQName = listSimpleType.getQName();
 2565                       if (itemTypeQName == null) {
 2566                           // we create a fake Qname for all these simple types since most propably they don't have one
 2567                           itemTypeQName = new QName(parentSimpleTypeQname.getNamespaceURI(), parentSimpleTypeQname.getLocalPart() + "_type0");
 2568                       }
 2569                       processSimpleSchemaType(listSimpleType, null, parentSchema, itemTypeQName);
 2570   
 2571                   }
 2572   
 2573                   String className = findClassName(itemTypeQName, false);
 2574                   metaInfHolder.setList(true);
 2575                   metaInfHolder.setItemTypeQName(itemTypeQName);
 2576                   metaInfHolder.setItemTypeClassName(className);
 2577   
 2578               }
 2579           }
 2580           return metaInfHolder;
 2581       }
 2582   
 2583   
 2584       /**
 2585        * Find whether a given particle is an array. The logic for deciding
 2586        * whether a given particle is an array is depending on their minOccurs
 2587        * and maxOccurs counts. If Maxoccurs is greater than one (1) then the
 2588        * content is an array.
 2589        * Also no higher level element will have the maxOccurs greater than one
 2590        *
 2591        * @param particle
 2592        * @throws SchemaCompilationException
 2593        */
 2594       private boolean isArray(XmlSchemaParticle particle) throws SchemaCompilationException {
 2595           long minOccurs = particle.getMinOccurs();
 2596           long maxOccurs = particle.getMaxOccurs();
 2597   
 2598           if (maxOccurs < minOccurs) {
 2599               throw new SchemaCompilationException();
 2600           } else {
 2601               return (maxOccurs > 1);
 2602           }
 2603   
 2604       }
 2605   
 2606       HashMap mapTypeCount = new HashMap();
 2607       private String getNextTypeSuffix(String localName) {
 2608           Integer typeCounter = (Integer) mapTypeCount.get(localName);
 2609           int count = 0;
 2610           if (typeCounter != null) {
 2611               if(typeCounter.intValue() == Integer.MAX_VALUE) {
 2612                   count = 0;
 2613               } else {
 2614                   count = typeCounter.intValue();
 2615               }
 2616           }
 2617           mapTypeCount.put(localName, new Integer(count+1));
 2618           return ("_type" + count);
 2619       }
 2620   
 2621       /**
 2622        * returns the parent schema of the componet having QName compoentTypeQName.
 2623        * withe the componet type.
 2624        * @param parentSchema - parent schema of the given componet
 2625        * @param componentQName - qname of the componet, of which we want to get the parent schema
 2626        * @param componetType - type of the componet. this can either be type,element,attribute or attribute group
 2627        * @return parent schema.
 2628        */
 2629   
 2630       private XmlSchema getParentSchema(XmlSchema parentSchema,
 2631                                         QName componentQName,
 2632                                         int componetType) throws SchemaCompilationException {
 2633           // if the componet do not have a propernamesapce or
 2634           // it is equals to the xsd schema namesapce
 2635           // we do not have to do any thing.
 2636           if ((componentQName == null) ||
 2637                 (componentQName.getNamespaceURI() == null) ||
 2638                   Constants.URI_2001_SCHEMA_XSD.equals(componentQName.getNamespaceURI())){
 2639               return parentSchema;
 2640           }
 2641   
 2642           List visitedSchemas = new ArrayList();
 2643           visitedSchemas.add(parentSchema);
 2644           XmlSchema newParentSchema = getParentSchemaFromIncludes(parentSchema,
 2645                   componentQName,componetType,visitedSchemas);
 2646           if (newParentSchema == null){
 2647               String targetNamespace = componentQName.getNamespaceURI();
 2648               if (loadedSchemaMap.containsKey(targetNamespace)){
 2649                   XmlSchema tempSchema = (XmlSchema) loadedSchemaMap.get(targetNamespace);
 2650                   if (isComponetExists(tempSchema,componentQName,componetType)){
 2651                       newParentSchema = tempSchema;
 2652                   }
 2653               } else if (availableSchemaMap.containsKey(targetNamespace)){
 2654                   XmlSchema tempSchema = (XmlSchema) availableSchemaMap.get(targetNamespace);
 2655                   if (isComponetExists(tempSchema,componentQName,componetType)){
 2656                       compile(tempSchema);
 2657                       newParentSchema = tempSchema;
 2658                   }
 2659               }
 2660           }
 2661           return newParentSchema;
 2662       }
 2663   
 2664       private XmlSchema getParentSchemaFromIncludes(XmlSchema parentSchema,
 2665                                                     QName componentQName,
 2666                                                     int componetType,
 2667                                                     List visitedSchemas) throws SchemaCompilationException {
 2668   
 2669           XmlSchema newParentSchema = null;
 2670           if (isComponetExists(parentSchema, componentQName, componetType)) {
 2671               newParentSchema = parentSchema;
 2672           } else {
 2673               // this componet must either be in a import or and include
 2674               XmlSchemaObjectCollection includes = parentSchema.getIncludes();
 2675               if (includes != null) {
 2676                   Object externalComponet = null;
 2677                   XmlSchema externalSchema = null;
 2678                   for (Iterator iter = includes.getIterator(); iter.hasNext();) {
 2679                       externalComponet = iter.next();
 2680                       if (externalComponet instanceof XmlSchemaExternal) {
 2681                           externalSchema = ((XmlSchemaExternal) externalComponet).getSchema();
 2682   
 2683                           // if this is an inline import without a schema location
 2684                           // xmlschema does not load the schema.
 2685                           // so we try to figure out it either from the available schemas
 2686                           // or from the laded schemas.
 2687                           if ((externalSchema == null) && externalComponet instanceof XmlSchemaImport){
 2688                               XmlSchemaImport xmlSchemaImport = (XmlSchemaImport) externalComponet;
 2689                               String importNamespce = xmlSchemaImport.getNamespace();
 2690                               if ((importNamespce != null) && !importNamespce.equals(Constants.URI_2001_SCHEMA_XSD)) {
 2691                                   if (loadedSchemaMap.containsKey(importNamespce)) {
 2692                                       externalSchema = (XmlSchema) loadedSchemaMap.get(importNamespce);
 2693                                   } else if (availableSchemaMap.containsKey(importNamespce)) {
 2694                                       XmlSchema tempSchema = (XmlSchema) availableSchemaMap.get(importNamespce);
 2695                                       compile(tempSchema);
 2696                                       externalSchema = tempSchema;
 2697                                   }
 2698                               }
 2699                           }
 2700                           if (externalSchema != null) {
 2701                               // find the componet in the new external schema.
 2702                               if (!visitedSchemas.contains(externalSchema)){
 2703                                   visitedSchemas.add(externalSchema);
 2704                                   newParentSchema = getParentSchemaFromIncludes(externalSchema,
 2705                                           componentQName, componetType, visitedSchemas);
 2706                               }
 2707                           }
 2708                           if (newParentSchema != null) {
 2709                               // i.e we have found the schema
 2710                               break;
 2711                           }
 2712                       }
 2713                   }
 2714               }
 2715           }
 2716           return newParentSchema;
 2717       }
 2718   
 2719       private boolean isComponetExists(XmlSchema schema,
 2720                                        QName componentQName,
 2721                                        int componetType) {
 2722           boolean isExists = false;
 2723           if (!schema.getTargetNamespace().equals(componentQName.getNamespaceURI())){
 2724                return false;
 2725           }
 2726           switch (componetType) {
 2727               case COMPONENT_TYPE : {
 2728                   isExists = (schema.getTypeByName(componentQName.getLocalPart()) != null);
 2729                   break;
 2730               }
 2731               case COMPONENT_ELEMENT : {
 2732                   isExists = (schema.getElementByName(componentQName.getLocalPart()) != null);
 2733                   break;
 2734               }
 2735               case COMPONENT_ATTRIBUTE : {
 2736                   isExists = (schema.getAttributes().getItem(componentQName) != null);
 2737                   break;
 2738               }
 2739               case COMPONENT_ATTRIBUTE_GROUP : {
 2740                   isExists = (schema.getAttributeGroups().getItem(componentQName) != null);
 2741                   break;
 2742               }
 2743               case COMPONENT_GROUP : {
 2744                   isExists = (schema.getGroups().getItem(componentQName) != null);
 2745                   break;
 2746               }
 2747           }
 2748          return isExists;
 2749       }
 2750   }

Save This Page
Home » axis2-1.5-src » org.apache » axis2 » schema » [javadoc | source]