Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » schema » [javadoc | source]

    1   /*   Copyright 2004 The Apache Software Foundation
    2    *
    3    *   Licensed under the Apache License, Version 2.0 (the "License");
    4    *   you may not use this file except in compliance with the License.
    5    *   You may obtain a copy of the License at
    6    *
    7    *       http://www.apache.org/licenses/LICENSE-2.0
    8    *
    9    *   Unless required by applicable law or agreed to in writing, software
   10    *   distributed under the License is distributed on an "AS IS" BASIS,
   11    *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   12    *   See the License for the specific language governing permissions and
   13    *  limitations under the License.
   14    */
   15   
   16   package org.apache.xmlbeans.impl.schema;
   17   
   18   import org.apache.xmlbeans.Filer;
   19   import org.apache.xmlbeans.QNameSet;
   20   import org.apache.xmlbeans.SchemaAnnotation;
   21   import org.apache.xmlbeans.SchemaAttributeGroup;
   22   import org.apache.xmlbeans.SchemaAttributeModel;
   23   import org.apache.xmlbeans.SchemaComponent;
   24   import org.apache.xmlbeans.SchemaField;
   25   import org.apache.xmlbeans.SchemaGlobalAttribute;
   26   import org.apache.xmlbeans.SchemaGlobalElement;
   27   import org.apache.xmlbeans.SchemaIdentityConstraint;
   28   import org.apache.xmlbeans.SchemaLocalAttribute;
   29   import org.apache.xmlbeans.SchemaLocalElement;
   30   import org.apache.xmlbeans.SchemaModelGroup;
   31   import org.apache.xmlbeans.SchemaParticle;
   32   import org.apache.xmlbeans.SchemaProperty;
   33   import org.apache.xmlbeans.SchemaStringEnumEntry;
   34   import org.apache.xmlbeans.SchemaType;
   35   import org.apache.xmlbeans.SchemaTypeLoader;
   36   import org.apache.xmlbeans.SchemaTypeLoaderException;
   37   import org.apache.xmlbeans.SchemaTypeSystem;
   38   import org.apache.xmlbeans.SimpleValue;
   39   import org.apache.xmlbeans.SystemProperties;
   40   import org.apache.xmlbeans.XmlAnySimpleType;
   41   import org.apache.xmlbeans.XmlObject;
   42   import org.apache.xmlbeans.XmlOptions;
   43   import org.apache.xmlbeans.ResourceLoader;
   44   import org.apache.xmlbeans.impl.common.NameUtil;
   45   import org.apache.xmlbeans.impl.common.QNameHelper;
   46   import org.apache.xmlbeans.impl.common.XBeanDebug;
   47   import org.apache.xmlbeans.impl.util.FilerImpl;
   48   import org.apache.xmlbeans.impl.util.HexBin;
   49   import org.apache.xmlbeans.impl.values.XmlObjectBase;
   50   import org.apache.xmlbeans.impl.xb.xsdschema.AttributeGroupDocument;
   51   import org.apache.xmlbeans.impl.xb.xsdschema.GroupDocument;
   52   import org.apache.xmlbeans.soap.SOAPArrayType;
   53   import org.apache.xmlbeans.soap.SchemaWSDLArrayType;
   54   import repackage.Repackager;
   55   
   56   import javax.xml.namespace.QName;
   57   import java.io.ByteArrayOutputStream;
   58   import java.io.DataInputStream;
   59   import java.io.DataOutputStream;
   60   import java.io.File;
   61   import java.io.IOException;
   62   import java.io.InputStream;
   63   import java.io.OutputStream;
   64   import java.math.BigInteger;
   65   import java.util.ArrayList;
   66   import java.util.Arrays;
   67   import java.util.Collections;
   68   import java.util.HashMap;
   69   import java.util.HashSet;
   70   import java.util.Iterator;
   71   import java.util.LinkedHashMap;
   72   import java.util.LinkedHashSet;
   73   import java.util.List;
   74   import java.util.Map;
   75   import java.util.Random;
   76   import java.util.Set;
   77   import java.util.zip.ZipEntry;
   78   import java.util.zip.ZipFile;
   79   
   80   public class SchemaTypeSystemImpl extends SchemaTypeLoaderBase implements SchemaTypeSystem
   81   {
   82       public static final int DATA_BABE = 0xDA7ABABE;
   83       public static final int MAJOR_VERSION = 2;  // must match == to be compatible
   84       public static final int MINOR_VERSION = 24; // must be <= to be compatible
   85       public static final int RELEASE_NUMBER = 0; // should be compatible even if < or >
   86   
   87       public static final int FILETYPE_SCHEMAINDEX = 1;
   88       public static final int FILETYPE_SCHEMATYPE = 2;
   89       public static final int FILETYPE_SCHEMAELEMENT = 3;
   90       public static final int FILETYPE_SCHEMAATTRIBUTE = 4;
   91       public static final int FILETYPE_SCHEMAPOINTER = 5;
   92       public static final int FILETYPE_SCHEMAMODELGROUP = 6;
   93       public static final int FILETYPE_SCHEMAATTRIBUTEGROUP = 7;
   94       public static final int FILETYPE_SCHEMAIDENTITYCONSTRAINT = 8;
   95   
   96       public static final int FLAG_PART_SKIPPABLE = 1;
   97       public static final int FLAG_PART_FIXED = 4;
   98       public static final int FLAG_PART_NILLABLE = 8;
   99       public static final int FLAG_PART_BLOCKEXT = 16;
  100       public static final int FLAG_PART_BLOCKREST = 32;
  101       public static final int FLAG_PART_BLOCKSUBST = 64;
  102       public static final int FLAG_PART_ABSTRACT = 128;
  103       public static final int FLAG_PART_FINALEXT = 256;
  104       public static final int FLAG_PART_FINALREST = 512;
  105   
  106       public static final int FLAG_PROP_ISATTR = 1;
  107       public static final int FLAG_PROP_JAVASINGLETON = 2;
  108       public static final int FLAG_PROP_JAVAOPTIONAL = 4;
  109       public static final int FLAG_PROP_JAVAARRAY = 8;
  110   
  111       public static final int FIELD_NONE = 0;
  112       public static final int FIELD_GLOBAL = 1;
  113       public static final int FIELD_LOCALATTR = 2;
  114       public static final int FIELD_LOCALELT = 3;
  115   
  116       // type flags
  117       static final int FLAG_SIMPLE_TYPE     = 0x1;
  118       static final int FLAG_DOCUMENT_TYPE   = 0x2;
  119       static final int FLAG_ORDERED         = 0x4;
  120       static final int FLAG_BOUNDED         = 0x8;
  121       static final int FLAG_FINITE          = 0x10;
  122       static final int FLAG_NUMERIC         = 0x20;
  123       static final int FLAG_STRINGENUM      = 0x40;
  124       static final int FLAG_UNION_OF_LISTS  = 0x80;
  125       static final int FLAG_HAS_PATTERN     = 0x100;
  126       static final int FLAG_ORDER_SENSITIVE = 0x200;
  127       static final int FLAG_TOTAL_ORDER     = 0x400;
  128       static final int FLAG_COMPILED        = 0x800;
  129       static final int FLAG_BLOCK_EXT       = 0x1000;
  130       static final int FLAG_BLOCK_REST      = 0x2000;
  131       static final int FLAG_FINAL_EXT       = 0x4000;
  132       static final int FLAG_FINAL_REST      = 0x8000;
  133       static final int FLAG_FINAL_UNION     = 0x10000;
  134       static final int FLAG_FINAL_LIST      = 0x20000;
  135       static final int FLAG_ABSTRACT        = 0x40000;
  136       static final int FLAG_ATTRIBUTE_TYPE  = 0x80000;
  137   
  138       /**
  139        * This is to support the feature of a separate/private XMLBeans
  140        * distribution that will not colide with the public org apache
  141        * xmlbeans one.
  142        * METADATA_PACKAGE_GEN will be "" for the original and something like
  143        * com_mycompany_private_xmlbeans for a private distribution of XMLBeans.
  144        *
  145        * There are two properties:
  146        *   METADATA_PACKAGE_GEN - used for generating metadata
  147        *   and METADATA_PACKAGE_LOAD - used for loading the metadata.
  148        * Most of the time they have the same value, with one exception, during the
  149        * repackage process scomp needs to load from old package and generate into
  150        * a new package.
  151        */
  152       public static String METADATA_PACKAGE_GEN;
  153       static
  154       {
  155           // fix for maven classloader
  156           Package stsPackage = SchemaTypeSystem.class.getPackage();
  157           String stsPackageName = (stsPackage==null) ?
  158               SchemaTypeSystem.class.getName().substring(0, SchemaTypeSystem.class.getName().lastIndexOf(".")) :
  159               stsPackage.getName();
  160   
  161           METADATA_PACKAGE_GEN = stsPackageName.replaceAll("\\.", "_");
  162       }
  163   
  164       private static String nameToPathString(String nameForSystem)
  165       {
  166           nameForSystem = nameForSystem.replace('.', '/');
  167   
  168           if (!nameForSystem.endsWith("/") && nameForSystem.length() > 0)
  169               nameForSystem = nameForSystem + "/";
  170   
  171           return nameForSystem;
  172       }
  173   
  174       public SchemaTypeSystemImpl(Class indexclass)
  175       {
  176           String fullname = indexclass.getName();
  177           _name = fullname.substring(0, fullname.lastIndexOf('.'));
  178           XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Loading type system " + _name, 1);
  179           _basePackage = nameToPathString(_name);
  180           _classloader = indexclass.getClassLoader();
  181           _linker = SchemaTypeLoaderImpl.build(null, null, _classloader);
  182           _resourceLoader = new ClassLoaderResourceLoader(_classloader);
  183           try
  184           {
  185               initFromHeader();
  186           }
  187           catch (RuntimeException e)
  188           {
  189               XBeanDebug.logException(e);
  190               throw e;
  191           }
  192           catch (Error e)
  193           {
  194               XBeanDebug.logException(e);
  195               throw e;
  196           }
  197           XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished loading type system " + _name, -1);
  198       }
  199   
  200       public static boolean fileContainsTypeSystem(File file, String name)
  201       {
  202           String indexname = nameToPathString(name) + "index.xsb";
  203   
  204           if (file.isDirectory())
  205           {
  206               return (new File(file, indexname)).isFile();
  207           }
  208           else
  209           {
  210               ZipFile zipfile = null;
  211               try
  212               {
  213                   zipfile = new ZipFile(file);
  214                   ZipEntry entry = zipfile.getEntry(indexname);
  215                   return (entry != null && !entry.isDirectory());
  216               }
  217               catch (IOException e)
  218               {
  219                   XBeanDebug.log("Problem loading SchemaTypeSystem, zipfilename " + file);
  220                   XBeanDebug.logException(e);
  221                   throw new SchemaTypeLoaderException(e.getMessage(), name, "index", SchemaTypeLoaderException.IO_EXCEPTION);
  222               }
  223               finally
  224               {
  225                   if (zipfile != null)
  226                       try { zipfile.close(); } catch (IOException e) {}
  227               }
  228           }
  229       }
  230   
  231       public static SchemaTypeSystemImpl forName(String name, ClassLoader loader)
  232       {
  233           try
  234           {
  235               Class c = Class.forName(name + "." + SchemaTypeCodePrinter.INDEX_CLASSNAME, true, loader);
  236               return (SchemaTypeSystemImpl)c.getField("typeSystem").get(null);
  237           }
  238           catch (Exception e)
  239           {
  240               return null;
  241           }
  242       }
  243   
  244       public SchemaTypeSystemImpl(ResourceLoader resourceLoader, String name, SchemaTypeLoader linker)
  245       {
  246           _name = name;
  247           _basePackage = nameToPathString(_name);
  248           _linker = linker;
  249           _resourceLoader = resourceLoader;
  250           try
  251           {
  252               initFromHeader();
  253           }
  254           catch (RuntimeException e)
  255           {
  256               XBeanDebug.logException(e);
  257               throw e;
  258           }
  259           catch (Error e)
  260           {
  261               XBeanDebug.logException(e);
  262               throw e;
  263           }
  264       }
  265   
  266       private void initFromHeader()
  267       {
  268           XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Reading unresolved handles for type system " + _name, 0);
  269           XsbReader reader = null;
  270           try
  271           {
  272               // Read the index file, which starts with a header.
  273               reader = new XsbReader("index", FILETYPE_SCHEMAINDEX);
  274   
  275               // has a handle pool (count, handle/type, handle/type...)
  276               _localHandles = new HandlePool();
  277               reader.readHandlePool(_localHandles);
  278   
  279               // then a qname map of global elements (count, qname/handle, qname/handle...)
  280               _globalElements = reader.readQNameRefMap();
  281   
  282               // qname map of global attributes
  283               _globalAttributes = reader.readQNameRefMap();
  284   
  285               // qname map of model groups
  286               _modelGroups = reader.readQNameRefMap();
  287   
  288               // qname map of attribute groups
  289               _attributeGroups = reader.readQNameRefMap();
  290   
  291               _identityConstraints = reader.readQNameRefMap();
  292   
  293               // qname map of global types
  294               _globalTypes = reader.readQNameRefMap();
  295   
  296               // qname map of document types, by the qname of the contained element
  297               _documentTypes = reader.readQNameRefMap();
  298   
  299               // qname mape of attribute types, by the qname of the contained attribute
  300               _attributeTypes = reader.readQNameRefMap();
  301   
  302               // string map of all types, by fully qualified classname
  303               _typeRefsByClassname = reader.readClassnameRefMap();
  304   
  305               _namespaces = reader.readNamespaces();
  306   
  307               // support for redefine, at the end of the file
  308               List typeNames = new ArrayList();
  309               List modelGroupNames = new ArrayList();
  310               List attributeGroupNames = new ArrayList();
  311               if (reader.atLeast(2, 15, 0))
  312               {
  313                   _redefinedGlobalTypes = reader.readQNameRefMapAsList(typeNames);
  314                   _redefinedModelGroups = reader.readQNameRefMapAsList(modelGroupNames);
  315                   _redefinedAttributeGroups = reader.readQNameRefMapAsList(attributeGroupNames);
  316               }
  317               if (reader.atLeast(2, 19, 0))
  318               {
  319                   _annotations = reader.readAnnotations();
  320               }
  321   
  322               buildContainers(typeNames, modelGroupNames, attributeGroupNames);
  323           }
  324           finally
  325           {
  326               if (reader != null)
  327                   reader.readEnd();
  328           }
  329       }
  330   
  331       void saveIndex()
  332       {
  333           String handle = "index";
  334           XsbReader saver = new XsbReader(handle);
  335           saver.writeIndexData();
  336           saver.writeRealHeader(handle, FILETYPE_SCHEMAINDEX);
  337           saver.writeIndexData();
  338           saver.writeEnd();
  339       }
  340   
  341       void savePointers()
  342       {
  343           savePointersForComponents(globalElements(), "schema" + METADATA_PACKAGE_GEN + "/element/");
  344           savePointersForComponents(globalAttributes(), "schema" + METADATA_PACKAGE_GEN + "/attribute/");
  345           savePointersForComponents(modelGroups(), "schema" + METADATA_PACKAGE_GEN + "/modelgroup/");
  346           savePointersForComponents(attributeGroups(), "schema" + METADATA_PACKAGE_GEN + "/attributegroup/");
  347           savePointersForComponents(globalTypes(), "schema" + METADATA_PACKAGE_GEN + "/type/");
  348           savePointersForComponents(identityConstraints(), "schema" + METADATA_PACKAGE_GEN + "/identityconstraint/");
  349           savePointersForNamespaces(_namespaces, "schema" + METADATA_PACKAGE_GEN + "/namespace/");
  350           savePointersForClassnames(_typeRefsByClassname.keySet(), "schema" + METADATA_PACKAGE_GEN + "/javaname/");
  351           savePointersForComponents(redefinedModelGroups(), "schema" + METADATA_PACKAGE_GEN + "/redefinedmodelgroup/");
  352           savePointersForComponents(redefinedAttributeGroups(), "schema" + METADATA_PACKAGE_GEN + "/redefinedattributegroup/");
  353           savePointersForComponents(redefinedGlobalTypes(), "schema" + METADATA_PACKAGE_GEN + "/redefinedtype/");
  354       }
  355   
  356       void savePointersForComponents(SchemaComponent[] components, String dir)
  357       {
  358           for (int i = 0; i < components.length; i++)
  359           {
  360               savePointerFile(dir + QNameHelper.hexsafedir(components[i].getName()), _name);
  361           }
  362       }
  363   
  364       void savePointersForClassnames(Set classnames, String dir)
  365       {
  366           for (Iterator i = classnames.iterator(); i.hasNext(); )
  367           {
  368               String classname = (String)i.next();
  369               savePointerFile(dir + classname.replace('.', '/'), _name);
  370           }
  371       }
  372   
  373       void savePointersForNamespaces(Set namespaces, String dir)
  374       {
  375           for (Iterator i = namespaces.iterator(); i.hasNext(); )
  376           {
  377               String ns = (String)i.next();
  378               savePointerFile(dir + QNameHelper.hexsafedir(new QName(ns, "xmlns")), _name);
  379           }
  380       }
  381   
  382       void savePointerFile(String filename, String name)
  383       {
  384           XsbReader saver = new XsbReader(filename);
  385           saver.writeString(name);
  386           saver.writeRealHeader(filename, FILETYPE_SCHEMAPOINTER);
  387           saver.writeString(name);
  388           saver.writeEnd();
  389       }
  390   
  391       /**
  392        * The strategy here is to copy the compiled TypeSystemHolder.template class
  393        * to a new TypeSystemHolder.class needed by the schema type system.  When
  394        * saving a loader, we read the TypeSystemHolder.template class file and
  395        * swap out the utf8 string constants with new ones to create a new
  396        * TypeSystemHolder class file.  This saves us the need to rely on javac
  397        * to compile a generated .java file into the class file.
  398        *
  399        * See the JVM spec on how to interpret the bytes of a class file.
  400        */
  401       void saveLoader()
  402       {
  403           String indexClassName = SchemaTypeCodePrinter.indexClassForSystem(this);
  404           String[] replace = makeClassStrings(indexClassName);
  405           assert replace.length == HOLDER_TEMPLATE_NAMES.length;
  406   
  407           InputStream is = null;
  408           OutputStream os = null;
  409   
  410           DataInputStream in = null;
  411           DataOutputStream out = null;
  412   
  413           Repackager repackager = null;
  414           if (_filer instanceof FilerImpl)
  415               repackager = ((FilerImpl)_filer).getRepackager();
  416   
  417           try
  418           {
  419               is = SchemaTypeSystemImpl.class.getResourceAsStream(HOLDER_TEMPLATE_CLASSFILE);
  420               if (is == null)
  421                   throw new SchemaTypeLoaderException("couldn't find resource: " + HOLDER_TEMPLATE_CLASSFILE, _name, null, SchemaTypeLoaderException.IO_EXCEPTION);
  422               in = new DataInputStream(is);
  423   
  424               os = _filer.createBinaryFile(indexClassName.replace('.', '/') + ".class");
  425               out = new DataOutputStream(os);
  426   
  427               // java magic
  428               out.writeInt(in.readInt());
  429   
  430               // java minor and major version
  431               out.writeShort(in.readUnsignedShort());
  432               out.writeShort(in.readUnsignedShort());
  433   
  434               int poolsize = in.readUnsignedShort();
  435               out.writeShort(poolsize);
  436   
  437               // the constant pool is indexed from 1 to poolsize-1
  438               for (int i = 1; i < poolsize; i++)
  439               {
  440                   int tag = in.readUnsignedByte();
  441                   out.writeByte(tag);
  442   
  443                   switch (tag)
  444                   {
  445                       case CONSTANT_UTF8:
  446                           String value = in.readUTF();
  447                           out.writeUTF(repackageConstant(value, replace, repackager));
  448                           break;
  449   
  450                       case CONSTANT_CLASS:
  451                       case CONSTANT_STRING:
  452                           out.writeShort(in.readUnsignedShort());
  453                           break;
  454   
  455                       case CONSTANT_NAMEANDTYPE:
  456                       case CONSTANT_METHOD:
  457                       case CONSTANT_FIELD:
  458                       case CONSTANT_INTERFACEMETHOD:
  459                           out.writeShort(in.readUnsignedShort());
  460                           out.writeShort(in.readUnsignedShort());
  461                           break;
  462   
  463                       case CONSTANT_INTEGER:
  464                       case CONSTANT_FLOAT:
  465                           out.writeInt(in.readInt());
  466                           break;
  467   
  468                       case CONSTANT_LONG:
  469                       case CONSTANT_DOUBLE:
  470                           out.writeInt(in.readInt());
  471                           out.writeInt(in.readInt());
  472                           break;
  473   
  474                       default:
  475                           throw new RuntimeException("Unexpected constant type: " + tag);
  476                   }
  477               }
  478   
  479               // we're done with the class' constant pool,
  480               // we can just copy the rest of the bytes
  481               try
  482               {
  483                   while (true)
  484                       out.writeByte(in.readByte());
  485               }
  486               catch (java.io.EOFException e)
  487               {
  488                   // ok
  489               }
  490   
  491           }
  492           catch (IOException e)
  493           {
  494               // ok
  495           }
  496           finally
  497           {
  498               if (is != null) try { is.close(); } catch (Exception e) { }
  499               if (os != null) try { os.close(); } catch (Exception e) { }
  500           }
  501       }
  502   
  503       private static final String HOLDER_TEMPLATE_CLASS = "org.apache.xmlbeans.impl.schema.TypeSystemHolder";
  504       private static final String HOLDER_TEMPLATE_CLASSFILE = "TypeSystemHolder.template";
  505       private static final String[] HOLDER_TEMPLATE_NAMES = makeClassStrings(HOLDER_TEMPLATE_CLASS);
  506   
  507       // constant pool entry types
  508       private static final int CONSTANT_UTF8 = 1;
  509       private static final int CONSTANT_UNICODE = 2;
  510       private static final int CONSTANT_INTEGER = 3;
  511       private static final int CONSTANT_FLOAT = 4;
  512       private static final int CONSTANT_LONG = 5;
  513       private static final int CONSTANT_DOUBLE = 6;
  514       private static final int CONSTANT_CLASS = 7;
  515       private static final int CONSTANT_STRING = 8;
  516       private static final int CONSTANT_FIELD = 9;
  517       private static final int CONSTANT_METHOD = 10;
  518       private static final int CONSTANT_INTERFACEMETHOD = 11;
  519       private static final int CONSTANT_NAMEANDTYPE = 12;
  520   
  521       // MAX_UNSIGNED_SHORT
  522       private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1;
  523   
  524       private static String repackageConstant(String value, String[] replace, Repackager repackager)
  525       {
  526           for (int i = 0; i < HOLDER_TEMPLATE_NAMES.length; i++)
  527               if (HOLDER_TEMPLATE_NAMES[i].equals(value))
  528                   return replace[i];
  529   
  530           if (repackager != null)
  531               return repackager.repackage(new StringBuffer(value)).toString();
  532   
  533           return value;
  534       }
  535   
  536       /**
  537        * Construct an array of Strings found in a class file for a classname.
  538        * For the class name 'a.b.C' it will generate an array of:
  539        * 'a.b.C', 'a/b/C', 'La/b/C;', and 'class$a$b$C'.
  540        */
  541       private static String[] makeClassStrings(String classname)
  542       {
  543           String[] result = new String[4];
  544   
  545           result[0] = classname;
  546           result[1] = classname.replace('.', '/');
  547           result[2] = "L" + result[1] + ";";
  548           result[3] = "class$" + classname.replace('.', '$');
  549   
  550           return result;
  551       }
  552   
  553       /**
  554        * Only used in the nonbootstrapped case.
  555        */
  556       private Map buildTypeRefsByClassname()
  557       {
  558           List allSeenTypes = new ArrayList();
  559           Map result = new LinkedHashMap();
  560           allSeenTypes.addAll(Arrays.asList(documentTypes()));
  561           allSeenTypes.addAll(Arrays.asList(attributeTypes()));
  562           allSeenTypes.addAll(Arrays.asList(globalTypes()));
  563   
  564           // now fully javaize everything deeply.
  565           for (int i = 0; i < allSeenTypes.size(); i++)
  566           {
  567               SchemaType gType = (SchemaType)allSeenTypes.get(i);
  568               String className = gType.getFullJavaName();
  569               if (className != null)
  570               {
  571                   result.put(className.replace('$', '.'), gType.getRef());
  572               }
  573               allSeenTypes.addAll(Arrays.asList(gType.getAnonymousTypes()));
  574           }
  575           return result;
  576       }
  577   
  578       private Map buildTypeRefsByClassname(Map typesByClassname)
  579       {
  580           Map result = new LinkedHashMap();
  581           for (Iterator i = typesByClassname.keySet().iterator(); i.hasNext(); )
  582           {
  583               String className = (String)i.next();
  584               result.put(className, ((SchemaType)typesByClassname.get(className)).getRef());
  585           }
  586           return result;
  587       }
  588   
  589       private static Map buildComponentRefMap(SchemaComponent[] components)
  590       {
  591           Map result = new LinkedHashMap();
  592           for (int i = 0; i < components.length; i++)
  593               result.put(components[i].getName(), components[i].getComponentRef());
  594           return result;
  595       }
  596   
  597       private static List buildComponentRefList(SchemaComponent[] components)
  598       {
  599           List result = new ArrayList();
  600           for (int i = 0; i < components.length; i++)
  601               result.add(components[i].getComponentRef());
  602           return result;
  603       }
  604   
  605       private static Map buildDocumentMap(SchemaType[] types)
  606       {
  607           Map result = new LinkedHashMap();
  608           for (int i = 0; i < types.length; i++)
  609               result.put(types[i].getDocumentElementName(), types[i].getRef());
  610           return result;
  611       }
  612   
  613       private static Map buildAttributeTypeMap(SchemaType[] types)
  614       {
  615           Map result = new LinkedHashMap();
  616           for (int i = 0; i < types.length; i++)
  617               result.put(types[i].getAttributeTypeAttributeName(), types[i].getRef());
  618           return result;
  619       }
  620   
  621       // Container operation
  622       private SchemaContainer getContainer(String namespace)
  623       {
  624           return (SchemaContainer) _containers.get(namespace);
  625       }
  626   
  627       private void addContainer(String namespace)
  628       {
  629           SchemaContainer c = new SchemaContainer(namespace);
  630           c.setTypeSystem(this);
  631           _containers.put(namespace, c);
  632       }
  633   
  634       private SchemaContainer getContainerNonNull(String namespace)
  635       {
  636           SchemaContainer result = getContainer(namespace);
  637           if (result == null)
  638           {
  639               addContainer(namespace);
  640               result = getContainer(namespace);
  641           }
  642           return result;
  643       }
  644   
  645       // Only called during init
  646       private void buildContainers(List redefTypeNames, List redefModelGroupNames, List redefAttributeGroupNames)
  647       {
  648           // This method walks the reference maps and copies said references
  649           // into the appropriate container
  650           for (Iterator it = _globalElements.entrySet().iterator(); it.hasNext(); )
  651           {
  652               Map.Entry entry = (Map.Entry) it.next();
  653               String ns = ((QName) entry.getKey()).getNamespaceURI();
  654               getContainerNonNull(ns).addGlobalElement((SchemaGlobalElement.Ref) entry.getValue());
  655           }
  656           for (Iterator it = _globalAttributes.entrySet().iterator(); it.hasNext(); )
  657           {
  658               Map.Entry entry = (Map.Entry) it.next();
  659               String ns = ((QName) entry.getKey()).getNamespaceURI();
  660               getContainerNonNull(ns).addGlobalAttribute((SchemaGlobalAttribute.Ref) entry.getValue());
  661           }
  662           for (Iterator it = _modelGroups.entrySet().iterator(); it.hasNext(); )
  663           {
  664               Map.Entry entry = (Map.Entry) it.next();
  665               String ns = ((QName) entry.getKey()).getNamespaceURI();
  666               getContainerNonNull(ns).addModelGroup((SchemaModelGroup.Ref) entry.getValue());
  667           }
  668           for (Iterator it = _attributeGroups.entrySet().iterator(); it.hasNext(); )
  669           {
  670               Map.Entry entry = (Map.Entry) it.next();
  671               String ns = ((QName) entry.getKey()).getNamespaceURI();
  672               getContainerNonNull(ns).addAttributeGroup((SchemaAttributeGroup.Ref) entry.getValue());
  673           }
  674           for (Iterator it = _identityConstraints.entrySet().iterator(); it.hasNext(); )
  675           {
  676               Map.Entry entry = (Map.Entry) it.next();
  677               String ns = ((QName) entry.getKey()).getNamespaceURI();
  678               getContainerNonNull(ns).addIdentityConstraint((SchemaIdentityConstraint.Ref) entry.getValue());
  679           }
  680           for (Iterator it = _globalTypes.entrySet().iterator(); it.hasNext(); )
  681           {
  682               Map.Entry entry = (Map.Entry) it.next();
  683               String ns = ((QName) entry.getKey()).getNamespaceURI();
  684               getContainerNonNull(ns).addGlobalType((SchemaType.Ref) entry.getValue());
  685           }
  686           for (Iterator it = _documentTypes.entrySet().iterator(); it.hasNext(); )
  687           {
  688               Map.Entry entry = (Map.Entry) it.next();
  689               String ns = ((QName) entry.getKey()).getNamespaceURI();
  690               getContainerNonNull(ns).addDocumentType((SchemaType.Ref) entry.getValue());
  691           }
  692           for (Iterator it = _attributeTypes.entrySet().iterator(); it.hasNext(); )
  693           {
  694               Map.Entry entry = (Map.Entry) it.next();
  695               String ns = ((QName) entry.getKey()).getNamespaceURI();
  696               getContainerNonNull(ns).addAttributeType((SchemaType.Ref) entry.getValue());
  697           }
  698           // Some earlier .xsb versions don't have records for redefinitions
  699           if (_redefinedGlobalTypes != null && _redefinedModelGroups != null &&
  700               _redefinedAttributeGroups != null)
  701           {
  702               assert _redefinedGlobalTypes.size() == redefTypeNames.size();
  703               for (Iterator it = _redefinedGlobalTypes.iterator(), itname = redefTypeNames.iterator(); it.hasNext(); )
  704               {
  705                   String ns = ((QName) itname.next()).getNamespaceURI();
  706                   getContainerNonNull(ns).addRedefinedType((SchemaType.Ref) it.next());
  707               }
  708               for (Iterator it = _redefinedModelGroups.iterator(), itname = redefModelGroupNames.iterator(); it.hasNext(); )
  709               {
  710                   String ns = ((QName) itname.next()).getNamespaceURI();
  711                   getContainerNonNull(ns).addRedefinedModelGroup((SchemaModelGroup.Ref) it.next());
  712               }
  713               for (Iterator it = _redefinedAttributeGroups.iterator(), itname = redefAttributeGroupNames.iterator(); it.hasNext(); )
  714               {
  715                   String ns = ((QName) itname.next()).getNamespaceURI();
  716                   getContainerNonNull(ns).addRedefinedAttributeGroup((SchemaAttributeGroup.Ref) it.next());
  717               }
  718           }
  719           // Some earlier .xsb versions don't have records for annotations
  720           if (_annotations != null)
  721           {
  722               for (Iterator it = _annotations.iterator(); it.hasNext(); )
  723               {
  724                   SchemaAnnotation ann = (SchemaAnnotation) it.next();
  725                   // BUGBUG(radup)
  726                   getContainerNonNull("").addAnnotation(ann);
  727               }
  728           }
  729           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  730               ((SchemaContainer) it.next()).setImmutable();
  731       }
  732   
  733       /**
  734        * This is the crux of the container work and role.
  735        * It makes a sweep over all containers and fixes each container's
  736        * typesystem to point to this typesystem.
  737        * Because SchemaComponents have a link to their containers, this has as
  738        * effect all components now indirectly pointing to this typesystem
  739        * even though they (as well as the typesystem itself) are immutable.
  740        */
  741       private void fixupContainers()
  742       {
  743           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  744           {
  745               SchemaContainer container = (SchemaContainer) it.next();
  746               container.setTypeSystem(this);
  747               container.setImmutable();
  748           }
  749       }
  750   
  751       private void assertContainersSynchronized()
  752       {
  753           boolean assertEnabled = false;
  754           // This code basically checks whether asserts are enabled so we don't do
  755           // all the work if they arent
  756           assert assertEnabled = true;
  757           if (!assertEnabled)
  758               return;
  759           // global elements
  760           Map temp = new HashMap();
  761           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  762               temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalElements().toArray(new SchemaComponent[0])));
  763           assert _globalElements.equals(temp);
  764           // global attributes
  765           temp = new HashMap();
  766           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  767               temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalAttributes().toArray(new SchemaComponent[0])));
  768           assert _globalAttributes.equals(temp);
  769           // model groups
  770           temp = new HashMap();
  771           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  772               temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).modelGroups().toArray(new SchemaComponent[0])));
  773           assert _modelGroups.equals(temp);
  774           // redefined model groups
  775           Set temp2 = new HashSet();
  776           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  777               temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedModelGroups().toArray(new SchemaComponent[0])));
  778           assert new HashSet(_redefinedModelGroups).equals(temp2);
  779           // attribute groups
  780           temp = new HashMap();
  781           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  782               temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).attributeGroups().toArray(new SchemaComponent[0])));
  783           assert _attributeGroups.equals(temp);
  784           // redefined attribute groups
  785           temp2 = new HashSet();
  786           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  787               temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedAttributeGroups().toArray(new SchemaComponent[0])));
  788           assert new HashSet(_redefinedAttributeGroups).equals(temp2);
  789           // global types
  790           temp = new HashMap();
  791           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  792               temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).globalTypes().toArray(new SchemaComponent[0])));
  793           assert _globalTypes.equals(temp);
  794           // redefined global types
  795           temp2 = new HashSet();
  796           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  797               temp2.addAll(buildComponentRefList((SchemaComponent[]) ((SchemaContainer) it.next()).redefinedGlobalTypes().toArray(new SchemaComponent[0])));
  798           assert new HashSet(_redefinedGlobalTypes).equals(temp2);
  799           // document types
  800           temp = new HashMap();
  801           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  802               temp.putAll(buildDocumentMap((SchemaType[]) ((SchemaContainer) it.next()).documentTypes().toArray(new SchemaType[0])));
  803           assert _documentTypes.equals(temp);
  804           // attribute types
  805           temp = new HashMap();
  806           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  807               temp.putAll(buildAttributeTypeMap((SchemaType[]) ((SchemaContainer) it.next()).attributeTypes().toArray(new SchemaType[0])));
  808           assert _attributeTypes.equals(temp);
  809           // identity constraints
  810           temp = new HashMap();
  811           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  812               temp.putAll(buildComponentRefMap((SchemaComponent[]) ((SchemaContainer) it.next()).identityConstraints().toArray(new SchemaComponent[0])));
  813           assert _identityConstraints.equals(temp);
  814           // annotations
  815           temp2 = new HashSet();
  816           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  817               temp2.addAll(((SchemaContainer) it.next()).annotations());
  818           assert new HashSet(_annotations).equals(temp2);
  819           // namespaces
  820           temp2 = new HashSet();
  821           for (Iterator it = _containers.values().iterator(); it.hasNext(); )
  822               temp2.add(((SchemaContainer) it.next()).getNamespace());
  823           assert _namespaces.equals(temp2);
  824       }
  825   
  826       private static Random _random;
  827       private static byte[] _mask = new byte[128 / 8];
  828   
  829       /**
  830        * Fun, fun.  Produce 128 bits of uniqueness randomly.
  831        * We used to use SecureRandom, but now we don't because SecureRandom
  832        * hits the filesystem and hangs us on a filesystem lock.  It also eats
  833        * a thread and other expensive resources.. :-).
  834        *
  835        * We don't really care that non-secure Random() can only do 48 bits of
  836        * randomness, since we're certainly not going to be called more than 2^48
  837        * times within our process lifetime.
  838        *
  839        * Our real concern is that by seeding Random() with the current
  840        * time, two users will end up with the same bits if they start a
  841        * schema compilation within the same millisecond.  That makes the
  842        * probability of collision in the real world slightly too high.
  843        * We're going to have millions of users, remember?  With a million
  844        * users, and one-compilation-per-day each, we'd see a collision every
  845        * few months.
  846        *
  847        * So we'll just xor the results of random with our few extra
  848        * bits of information computed below to help reduce the probability
  849        * of collision by a few decimal places.  To collide, you will have had
  850        * to have the same amount of free memory, the same user name, timezone,
  851        * and country, the same current directory, the same java classpath,
  852        * the same operating system and jvm version, and the same choices of
  853        * identity hashcodes for a few objects. And be started within the same
  854        * millisecond. Or you can collide if you have a cosmic 128-bit mathematical
  855        * coincidence. No worries.
  856        */
  857       private static synchronized void nextBytes(byte[] result)
  858       {
  859           if (_random == null)
  860           {
  861               try
  862               {
  863                   ByteArrayOutputStream baos = new ByteArrayOutputStream();
  864                   DataOutputStream daos = new DataOutputStream(baos);
  865   
  866                   // at least 10 bits of unqieueness, right?  Maybe even 50 or 60.
  867                   daos.writeInt(System.identityHashCode(SchemaTypeSystemImpl.class));
  868                   String[] props = new String[] { "user.name", "user.dir", "user.timezone", "user.country", "java.class.path", "java.home", "java.vendor", "java.version", "os.version" };
  869                   for (int i = 0; i < props.length; i++)
  870                   {
  871                       String prop = SystemProperties.getProperty(props[i]);
  872                       if (prop != null)
  873                       {
  874                           daos.writeUTF(prop);
  875                           daos.writeInt(System.identityHashCode(prop));
  876                       }
  877                   }
  878                   daos.writeLong(Runtime.getRuntime().freeMemory());
  879                   daos.close();
  880                   byte[] bytes = baos.toByteArray();
  881                   for (int i = 0; i < bytes.length; i++)
  882                   {
  883                       int j = i % _mask.length;
  884                       _mask[j] *= 21;
  885                       _mask[j] += i;
  886                   }
  887               }
  888               catch (IOException e)
  889               {
  890                   XBeanDebug.logException(e);
  891               }
  892   
  893               _random = new Random(System.currentTimeMillis());
  894           }
  895           _random.nextBytes(result);
  896           for (int i = 0; i < result.length; i++)
  897           {
  898               int j = i & _mask.length;
  899               result[i] ^= _mask[j];
  900           }
  901       }
  902   
  903       public SchemaTypeSystemImpl(String nameForSystem)
  904       {
  905           // if we have no name, select a random one
  906           if (nameForSystem == null)
  907           {
  908               // get 128 random bits (that'll be 32 hex digits)
  909               byte[] bytes = new byte[128/8];
  910               nextBytes(bytes);
  911               nameForSystem = "s" + new String(HexBin.encode(bytes));
  912           }
  913   
  914           _name = "schema" + METADATA_PACKAGE_GEN + ".system." + nameForSystem;
  915           _basePackage = nameToPathString(_name);
  916           _classloader = null;
  917           //System.out.println("             _base: " + _basePackage);
  918       }
  919   
  920       public void loadFromBuilder(SchemaGlobalElement[] globalElements,
  921                                   SchemaGlobalAttribute[] globalAttributes,
  922                                   SchemaType[] globalTypes,
  923                                   SchemaType[] documentTypes,
  924                                   SchemaType[] attributeTypes)
  925       {
  926           assert(_classloader == null);
  927           _localHandles = new HandlePool();
  928           _globalElements = buildComponentRefMap(globalElements);
  929           _globalAttributes = buildComponentRefMap(globalAttributes);
  930           _globalTypes = buildComponentRefMap(globalTypes);
  931           _documentTypes = buildDocumentMap(documentTypes);
  932           _attributeTypes = buildAttributeTypeMap(attributeTypes);
  933           _typeRefsByClassname = buildTypeRefsByClassname();
  934           buildContainers(Collections.EMPTY_LIST, Collections.EMPTY_LIST,
  935               Collections.EMPTY_LIST);
  936           _namespaces = new HashSet();
  937       }
  938   
  939       public void loadFromStscState(StscState state)
  940       {
  941           assert(_classloader == null);
  942           _localHandles = new HandlePool();
  943           _globalElements = buildComponentRefMap(state.globalElements());
  944           _globalAttributes = buildComponentRefMap(state.globalAttributes());
  945           _modelGroups = buildComponentRefMap(state.modelGroups());
  946           _redefinedModelGroups = buildComponentRefList(state.redefinedModelGroups());
  947           _attributeGroups = buildComponentRefMap(state.attributeGroups());
  948           _redefinedAttributeGroups = buildComponentRefList(state.redefinedAttributeGroups());
  949           _globalTypes = buildComponentRefMap(state.globalTypes());
  950           _redefinedGlobalTypes = buildComponentRefList(state.redefinedGlobalTypes());
  951           _documentTypes = buildDocumentMap(state.documentTypes());
  952           _attributeTypes = buildAttributeTypeMap(state.attributeTypes());
  953           _typeRefsByClassname = buildTypeRefsByClassname(state.typesByClassname());
  954           _identityConstraints = buildComponentRefMap(state.idConstraints());
  955           _annotations = state.annotations();
  956           _namespaces = new HashSet(Arrays.asList(state.getNamespaces()));
  957           _containers = state.getContainerMap();
  958           fixupContainers();
  959           // Checks that data in the containers matches the lookup maps
  960           assertContainersSynchronized();
  961           setDependencies(state.getDependencies());
  962       }
  963   
  964       final SchemaTypeSystemImpl getTypeSystem()
  965       {
  966           return this;
  967       }
  968   
  969       void setDependencies(SchemaDependencies deps)
  970       {   _deps = deps; }
  971   
  972       SchemaDependencies getDependencies()
  973       {   return _deps; }
  974       
  975       // EXPERIMENTAL
  976       public boolean isIncomplete() { return _incomplete; }
  977       
  978       // EXPERIMENTAL
  979       void setIncomplete(boolean incomplete) { _incomplete = incomplete; }
  980   
  981       static class StringPool
  982       {
  983           private List intsToStrings = new ArrayList();
  984           private Map stringsToInts = new HashMap();
  985           private String _handle;
  986           private String _name;
  987   
  988           /**
  989            * Constructs an empty StringPool to be filled with strings.
  990            */
  991           StringPool(String handle, String name)
  992           {
  993               _handle = handle;
  994               _name = name;
  995               intsToStrings.add(null);
  996           }
  997   
  998           int codeForString(String str)
  999           {
 1000               if (str == null)
 1001                   return 0;
 1002               Integer result = (Integer)stringsToInts.get(str);
 1003               if (result == null)
 1004               {
 1005                   result = new Integer(intsToStrings.size());
 1006                   intsToStrings.add(str);
 1007                   stringsToInts.put(str, result);
 1008               }
 1009               return result.intValue();
 1010           }
 1011   
 1012           String stringForCode(int code)
 1013           {
 1014               if (code == 0)
 1015                   return null;
 1016               return (String)intsToStrings.get(code);
 1017           }
 1018   
 1019           void writeTo(DataOutputStream output)
 1020           {
 1021               if (intsToStrings.size() >= MAX_UNSIGNED_SHORT)
 1022                   throw new SchemaTypeLoaderException("Too many strings (" + intsToStrings.size() + ")", _name, _handle, SchemaTypeLoaderException.INT_TOO_LARGE);
 1023   
 1024               try
 1025               {
 1026                   output.writeShort(intsToStrings.size());
 1027                   Iterator i = intsToStrings.iterator();
 1028                   for (i.next(); i.hasNext(); )
 1029                   {
 1030                       String str = (String)i.next();
 1031                       output.writeUTF(str);
 1032                   }
 1033               }
 1034               catch (IOException e)
 1035               {
 1036                   throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 1037               }
 1038           }
 1039   
 1040           void readFrom(DataInputStream input)
 1041           {
 1042               if (intsToStrings.size() != 1 || stringsToInts.size() != 0)
 1043                   throw new IllegalStateException();
 1044   
 1045               try
 1046               {
 1047                   int size = input.readUnsignedShort();
 1048                   for (int i = 1; i < size; i++)
 1049                   {
 1050                       String str = input.readUTF().intern();
 1051                       int code = codeForString(str);
 1052                       if (code != i)
 1053                           throw new IllegalStateException();
 1054                   }
 1055               }
 1056               catch (IOException e)
 1057               {
 1058                   throw new SchemaTypeLoaderException(e.getMessage() == null ? e.getMessage() : "IO Exception", _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e);
 1059               }
 1060           }
 1061       }
 1062   
 1063       class HandlePool
 1064       {
 1065           private Map _handlesToRefs = new LinkedHashMap();
 1066           private Map _componentsToHandles = new LinkedHashMap(); // populated on write
 1067           private boolean _started;
 1068   
 1069           /**
 1070            * Constructs an empty HandlePool to be populated.
 1071            */
 1072           HandlePool()
 1073           {
 1074           }
 1075   
 1076           private String addUniqueHandle(SchemaComponent obj, String base)
 1077           {
 1078               base = base.toLowerCase();  // we lowercase handles because of case-insensitive Windows filenames!!!
 1079               String handle = base;
 1080               for (int index = 2; _handlesToRefs.containsKey(handle); index++)
 1081               {
 1082                   handle = base + index;
 1083               }
 1084               _handlesToRefs.put(handle, obj.getComponentRef());
 1085               _componentsToHandles.put(obj, handle);
 1086               return handle;
 1087           }
 1088   
 1089           String handleForComponent(SchemaComponent comp)
 1090           {
 1091               if (comp == null)
 1092                   return null;
 1093               if (comp.getTypeSystem() != getTypeSystem())
 1094                   throw new IllegalArgumentException("Cannot supply handles for types from another type system");
 1095               if (comp instanceof SchemaType)
 1096                   return handleForType((SchemaType)comp);
 1097               if (comp instanceof SchemaGlobalElement)
 1098                   return handleForElement((SchemaGlobalElement)comp);
 1099               if (comp instanceof SchemaGlobalAttribute)
 1100                   return handleForAttribute((SchemaGlobalAttribute)comp);
 1101               if (comp instanceof SchemaModelGroup)
 1102                   return handleForModelGroup((SchemaModelGroup)comp);
 1103               if (comp instanceof SchemaAttributeGroup)
 1104                   return handleForAttributeGroup((SchemaAttributeGroup)comp);
 1105               if (comp instanceof SchemaIdentityConstraint)
 1106                   return handleForIdentityConstraint((SchemaIdentityConstraint)comp);
 1107               throw new IllegalStateException("Component type cannot have a handle");
 1108           }
 1109   
 1110           String handleForElement(SchemaGlobalElement element)
 1111           {
 1112               if (element == null)
 1113                   return null;
 1114               if (element.getTypeSystem() != getTypeSystem())
 1115                   throw new IllegalArgumentException("Cannot supply handles for types from another type system");
 1116               String handle = (String)_componentsToHandles.get(element);
 1117               if (handle == null)
 1118                   handle = addUniqueHandle(element, NameUtil.upperCamelCase(element.getName().getLocalPart()) + "Element");
 1119               return handle;
 1120           }
 1121   
 1122           String handleForAttribute(SchemaGlobalAttribute attribute)
 1123           {
 1124               if (attribute == null)
 1125                   return null;
 1126               if (attribute.getTypeSystem() != getTypeSystem())
 1127                   throw new IllegalArgumentException("Cannot supply handles for types from another type system");
 1128               String handle = (String)_componentsToHandles.get(attribute);
 1129               if (handle == null)
 1130                   handle = addUniqueHandle(attribute, NameUtil.upperCamelCase(attribute.getName().getLocalPart()) + "Attribute");
 1131               return handle;
 1132           }
 1133   
 1134           String handleForModelGroup(SchemaModelGroup group)
 1135           {
 1136               if (group == null)
 1137                   return null;
 1138               if (group.getTypeSystem() != getTypeSystem())
 1139                   throw new IllegalArgumentException("Cannot supply handles for types from another type system");
 1140               String handle = (String)_componentsToHandles.get(group);
 1141               if (handle == null)
 1142                   handle = addUniqueHandle(group, NameUtil.upperCamelCase(group.getName().getLocalPart()) + "ModelGroup");
 1143               return handle;
 1144           }
 1145   
 1146           String handleForAttributeGroup(SchemaAttributeGroup group)
 1147           {
 1148               if (group == null)
 1149                   return null;
 1150               if (group.getTypeSystem() != getTypeSystem())
 1151                   throw new IllegalArgumentException("Cannot supply handles for types from another type system");
 1152               String handle = (String)_componentsToHandles.get(group);
 1153               if (handle == null)
 1154                   handle = addUniqueHandle(group, NameUtil.upperCamelCase(group.getName().getLocalPart()) + "AttributeGroup");
 1155               return handle;
 1156           }
 1157   
 1158           String handleForIdentityConstraint(SchemaIdentityConstraint idc)
 1159           {
 1160               if (idc == null)
 1161                   return null;
 1162               if (idc.getTypeSystem() != getTypeSystem())
 1163                   throw new IllegalArgumentException("Cannot supply handles for types from another type system");
 1164               String handle = (String)_componentsToHandles.get(idc);
 1165               if (handle == null)
 1166                   handle = addUniqueHandle(idc, NameUtil.upperCamelCase(idc.getName().getLocalPart()) + "IdentityConstraint");
 1167               return handle;
 1168           }
 1169   
 1170           String handleForType(SchemaType type)
 1171           {
 1172               if (type == null)
 1173                   return null;
 1174               if (type.getTypeSystem() != getTypeSystem())
 1175                   throw new IllegalArgumentException("Cannot supply handles for types from another type system");
 1176               String handle = (String)_componentsToHandles.get(type);
 1177               if (handle == null)
 1178               {
 1179                   QName name = type.getName();
 1180                   String suffix = "";
 1181                   if (name == null)
 1182                   {
 1183                       if (type.isDocumentType())
 1184                       {
 1185                           name = type.getDocumentElementName();
 1186                           suffix = "Doc";
 1187                       }
 1188                       else if (type.isAttributeType())
 1189                       {
 1190                           name = type.getAttributeTypeAttributeName();
 1191                           suffix = "AttrType";
 1192                       }
 1193                       else if (type.getContainerField() != null)
 1194                       {
 1195                           name = type.getContainerField().getName();
 1196                           suffix = type.getContainerField().isAttribute() ? "Attr" : "Elem";
 1197                       }
 1198                   }
 1199   
 1200                   String baseName;
 1201                   String uniq = Integer.toHexString(type.toString().hashCode() | 0x80000000).substring(4).toUpperCase();
 1202                   if (name == null)
 1203                       baseName = "Anon" + uniq + "Type";
 1204                   else
 1205                       baseName = NameUtil.upperCamelCase(name.getLocalPart()) + uniq + suffix + "Type";
 1206   
 1207                   handle = addUniqueHandle(type, baseName);
 1208               }
 1209   
 1210               return handle;
 1211           }
 1212   
 1213           SchemaComponent.Ref refForHandle(String handle)
 1214           {
 1215               if (handle == null)
 1216                   return null;
 1217   
 1218               return (SchemaComponent.Ref)_handlesToRefs.get(handle);
 1219           }
 1220   
 1221           Set getAllHandles()
 1222           {
 1223               return _handlesToRefs.keySet();
 1224           }
 1225   
 1226           void startWriteMode()
 1227           {
 1228               _started = true;
 1229               _componentsToHandles = new LinkedHashMap();
 1230               for (Iterator i = _handlesToRefs.keySet().iterator(); i.hasNext(); )
 1231               {
 1232                   String handle = (String)i.next();
 1233   //                System.err.println("Writing preexisting handle " + handle);
 1234                   SchemaComponent comp = ((SchemaComponent.Ref)_handlesToRefs.get(handle)).getComponent();
 1235                   _componentsToHandles.put(comp, handle);
 1236               }
 1237           }
 1238   
 1239       }
 1240   
 1241       private String _name;
 1242       private String _basePackage;
 1243       
 1244       // EXPERIMENTAL: recovery from compilation errors and partial type systems
 1245       private boolean _incomplete = false;
 1246   
 1247       // classloader is available for sts's that were compiled and loaded, not dynamic ones
 1248       private ClassLoader _classloader;
 1249   
 1250       // the loader for loading .xsb resources
 1251       private ResourceLoader _resourceLoader;
 1252   
 1253       // the following is used to link references during load
 1254       SchemaTypeLoader _linker;
 1255   
 1256       private HandlePool _localHandles;
 1257       private Filer _filer;
 1258   
 1259       // top-level annotations
 1260       private List _annotations;
 1261   
 1262       // container
 1263       private Map _containers = new HashMap();
 1264       // dependencies
 1265       private SchemaDependencies _deps;
 1266   
 1267       private List _redefinedModelGroups;
 1268       private List _redefinedAttributeGroups;
 1269       private List _redefinedGlobalTypes;
 1270   
 1271       // actual type system data, map QNames -> SchemaComponent.Ref
 1272       private Map _globalElements;
 1273       private Map _globalAttributes;
 1274       private Map _modelGroups;
 1275       private Map _attributeGroups;
 1276       private Map _globalTypes;
 1277       private Map _documentTypes;
 1278       private Map _attributeTypes;
 1279       private Map _identityConstraints = Collections.EMPTY_MAP;
 1280       private Map _typeRefsByClassname = new HashMap();
 1281       private Set _namespaces;
 1282   
 1283       static private final SchemaType[] EMPTY_ST_ARRAY = new SchemaType[0];
 1284       static private final SchemaGlobalElement[] EMPTY_GE_ARRAY = new SchemaGlobalElement[0];
 1285       static private final SchemaGlobalAttribute[] EMPTY_GA_ARRAY = new SchemaGlobalAttribute[0];
 1286       static private final SchemaModelGroup[] EMPTY_MG_ARRAY = new SchemaModelGroup[0];
 1287       static private final SchemaAttributeGroup[] EMPTY_AG_ARRAY = new SchemaAttributeGroup[0];
 1288       static private final SchemaIdentityConstraint[] EMPTY_IC_ARRAY = new SchemaIdentityConstraint[0];
 1289       static private final SchemaAnnotation[] EMPTY_ANN_ARRAY = new SchemaAnnotation[0];
 1290   
 1291       public void saveToDirectory(File classDir)
 1292       {
 1293           save(new FilerImpl(classDir, null, null, false, false));
 1294       }
 1295   
 1296       public void save(Filer filer)
 1297       {
 1298           if (_incomplete)
 1299               throw new IllegalStateException("Incomplete SchemaTypeSystems cannot be saved.");
 1300   
 1301           if (filer == null)
 1302               throw new IllegalArgumentException("filer must not be null");
 1303           _filer = filer;
 1304   
 1305           _localHandles.startWriteMode();
 1306           saveTypesRecursively(globalTypes());
 1307           saveTypesRecursively(documentTypes());
 1308           saveTypesRecursively(attributeTypes());
 1309           saveGlobalElements(globalElements());
 1310           saveGlobalAttributes(globalAttributes());
 1311           saveModelGroups(modelGroups());
 1312           saveAttributeGroups(attributeGroups());
 1313           saveIdentityConstraints(identityConstraints());
 1314   
 1315           saveTypesRecursively(redefinedGlobalTypes());
 1316           saveModelGroups(redefinedModelGroups());
 1317           saveAttributeGroups(redefinedAttributeGroups());
 1318   
 1319           saveIndex();
 1320           savePointers();
 1321   
 1322           saveLoader();
 1323       }
 1324   
 1325       void saveTypesRecursively(SchemaType[] types)
 1326       {
 1327           for (int i = 0; i < types.length; i++)
 1328           {
 1329               if (types[i].getTypeSystem() != getTypeSystem())
 1330                   continue;
 1331               saveType(types[i]);
 1332               saveTypesRecursively(types[i].getAnonymousTypes());
 1333           }
 1334       }
 1335   
 1336       public void saveGlobalElements(SchemaGlobalElement[] elts)
 1337       {
 1338           if (_incomplete)
 1339               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1340           for (int i = 0; i < elts.length; i++)
 1341           {
 1342               saveGlobalElement(elts[i]);
 1343           }
 1344       }
 1345   
 1346       public void saveGlobalAttributes(SchemaGlobalAttribute[] attrs)
 1347       {
 1348           if (_incomplete)
 1349               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1350           for (int i = 0; i < attrs.length; i++)
 1351           {
 1352               saveGlobalAttribute(attrs[i]);
 1353           }
 1354       }
 1355   
 1356       public void saveModelGroups(SchemaModelGroup[] groups)
 1357       {
 1358           if (_incomplete)
 1359               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1360           for (int i = 0; i < groups.length; i++)
 1361           {
 1362               saveModelGroup(groups[i]);
 1363           }
 1364       }
 1365   
 1366       public void saveAttributeGroups(SchemaAttributeGroup[] groups)
 1367       {
 1368           if (_incomplete)
 1369               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1370           for (int i = 0; i < groups.length; i++)
 1371           {
 1372               saveAttributeGroup(groups[i]);
 1373           }
 1374       }
 1375   
 1376       public void saveIdentityConstraints(SchemaIdentityConstraint[] idcs)
 1377       {
 1378           if (_incomplete)
 1379               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1380           for (int i = 0; i < idcs.length; i++)
 1381           {
 1382               saveIdentityConstraint(idcs[i]);
 1383           }
 1384       }
 1385   
 1386       public void saveGlobalElement(SchemaGlobalElement elt)
 1387       {
 1388           if (_incomplete)
 1389               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1390           String handle = _localHandles.handleForElement(elt);
 1391           XsbReader saver = new XsbReader(handle);
 1392           saver.writeParticleData((SchemaParticle)elt);
 1393           saver.writeString(elt.getSourceName());
 1394           saver.writeRealHeader(handle, FILETYPE_SCHEMAELEMENT);
 1395           saver.writeParticleData((SchemaParticle)elt);
 1396           saver.writeString(elt.getSourceName());
 1397           saver.writeEnd();
 1398       }
 1399   
 1400       public void saveGlobalAttribute(SchemaGlobalAttribute attr)
 1401       {
 1402           if (_incomplete)
 1403               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1404           String handle = _localHandles.handleForAttribute(attr);
 1405           XsbReader saver = new XsbReader(handle);
 1406           saver.writeAttributeData(attr);
 1407           saver.writeString(attr.getSourceName());
 1408           saver.writeRealHeader(handle, FILETYPE_SCHEMAATTRIBUTE);
 1409           saver.writeAttributeData(attr);
 1410           saver.writeString(attr.getSourceName());
 1411           saver.writeEnd();
 1412       }
 1413   
 1414       public void saveModelGroup(SchemaModelGroup grp)
 1415       {
 1416           if (_incomplete)
 1417               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1418           String handle = _localHandles.handleForModelGroup(grp);
 1419           XsbReader saver = new XsbReader(handle);
 1420           saver.writeModelGroupData(grp);
 1421           saver.writeRealHeader(handle, FILETYPE_SCHEMAMODELGROUP);
 1422           saver.writeModelGroupData(grp);
 1423           saver.writeEnd();
 1424       }
 1425   
 1426       public void saveAttributeGroup(SchemaAttributeGroup grp)
 1427       {
 1428           if (_incomplete)
 1429               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1430           String handle = _localHandles.handleForAttributeGroup(grp);
 1431           XsbReader saver = new XsbReader(handle);
 1432           saver.writeAttributeGroupData(grp);
 1433           saver.writeRealHeader(handle, FILETYPE_SCHEMAATTRIBUTEGROUP);
 1434           saver.writeAttributeGroupData(grp);
 1435           saver.writeEnd();
 1436       }
 1437   
 1438       public void saveIdentityConstraint(SchemaIdentityConstraint idc)
 1439       {
 1440           if (_incomplete)
 1441               throw new IllegalStateException("This SchemaTypeSystem cannot be saved.");
 1442           String handle = _localHandles.handleForIdentityConstraint(idc);
 1443           XsbReader saver = new XsbReader(handle);
 1444           saver.writeIdConstraintData(idc);
 1445           saver.writeRealHeader(handle, FILETYPE_SCHEMAIDENTITYCONSTRAINT);
 1446           saver.writeIdConstraintData(idc);
 1447           saver.writeEnd();
 1448       }
 1449   
 1450       void saveType(SchemaType type)
 1451       {
 1452           String handle = _localHandles.handleForType(type);
 1453           XsbReader saver = new XsbReader(handle);
 1454           saver.writeTypeData(type);
 1455           saver.writeRealHeader(handle, FILETYPE_SCHEMATYPE);
 1456           saver.writeTypeData(type);
 1457           saver.writeEnd();
 1458       }
 1459   
 1460       public static String crackPointer(InputStream stream)
 1461       {
 1462           DataInputStream input = null;
 1463           try
 1464           {
 1465               input = new DataInputStream(stream);
 1466   
 1467               int magic = input.readInt();
 1468               if (magic != DATA_BABE)
 1469                   return null;
 1470   
 1471               int majorver = input.readShort();
 1472               int minorver = input.readShort();
 1473   
 1474               if (majorver != MAJOR_VERSION)
 1475                   return null;
 1476   
 1477               if (minorver > MINOR_VERSION)
 1478                   return null;
 1479   
 1480               if (majorver > 2 || majorver == 2 && minorver >= 18)
 1481                   input.readShort(); // release number present in atLeast(2, 18, 0)
 1482   
 1483               int actualfiletype = input.readShort();
 1484               if (actualfiletype != FILETYPE_SCHEMAPOINTER)
 1485                   return null;
 1486   
 1487               StringPool stringPool = new StringPool("pointer", "unk");
 1488               stringPool.readFrom(input);
 1489   
 1490               return stringPool.stringForCode(input.readShort());
 1491           }
 1492           catch (IOException e)
 1493           {
 1494               return null;
 1495           }
 1496           finally
 1497           {
 1498               if (input != null)
 1499                   try { input.close(); } catch (IOException e) {}
 1500           }
 1501       }
 1502   
 1503       private class XsbReader
 1504       {
 1505           DataInputStream _input;
 1506           DataOutputStream _output;
 1507           StringPool _stringPool;
 1508           String _handle;
 1509           private int _majorver;
 1510           private int _minorver;
 1511           private int _releaseno;
 1512           int _actualfiletype;
 1513   
 1514           public XsbReader(String handle, int filetype)
 1515           {
 1516               String resourcename = _basePackage + handle + ".xsb";
 1517               InputStream rawinput = getLoaderStream(resourcename);
 1518               if (rawinput == null)
 1519                   throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Could not locate compiled schema resource " + resourcename, _name, handle, SchemaTypeLoaderException.NO_RESOURCE);
 1520   
 1521               _input = new DataInputStream(rawinput);
 1522               _handle = handle;
 1523   
 1524               int magic = readInt();
 1525               if (magic != DATA_BABE)
 1526                   throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong magic cookie", _name, handle, SchemaTypeLoaderException.WRONG_MAGIC_COOKIE);
 1527   
 1528               _majorver = readShort();
 1529               _minorver = readShort();
 1530   
 1531               if (_majorver != MAJOR_VERSION)
 1532                   throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong major version - expecting " + MAJOR_VERSION + ", got " + _majorver, _name, handle, SchemaTypeLoaderException.WRONG_MAJOR_VERSION);
 1533   
 1534               if (_minorver > MINOR_VERSION)
 1535                   throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Incompatible minor version - expecting up to " + MINOR_VERSION + ", got " + _minorver, _name, handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION);
 1536   
 1537               // Clip to 14 because we're not backward compatible with earlier
 1538               // minor versions.  Remove this when upgrading to a new major
 1539               // version
 1540   
 1541               if (_minorver < 14)
 1542                   throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Incompatible minor version - expecting at least 14, got " + _minorver, _name, handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION);
 1543   
 1544               if (atLeast(2, 18, 0))
 1545                   _releaseno = readShort();
 1546   
 1547               int actualfiletype = readShort();
 1548               if (actualfiletype != filetype && filetype != 0xFFFF)
 1549                   throw new SchemaTypeLoaderException("XML-BEANS compiled schema: File has the wrong type - expecting type " + filetype + ", got type " + actualfiletype, _name, handle, SchemaTypeLoaderException.WRONG_FILE_TYPE);
 1550   
 1551               _stringPool = new StringPool(_handle, _name);
 1552               _stringPool.readFrom(_input);
 1553   
 1554               _actualfiletype = actualfiletype;
 1555           }
 1556   
 1557           protected boolean atLeast(int majorver, int minorver, int releaseno)
 1558           {
 1559               if (_majorver > majorver)
 1560                   return true;
 1561               if (_majorver < majorver)
 1562                   return false;
 1563               if (_minorver > minorver)
 1564                   return true;
 1565               if (_minorver < minorver)
 1566                   return false;
 1567               return (_releaseno >= releaseno);
 1568           }
 1569   
 1570           protected boolean atMost(int majorver, int minorver, int releaseno)
 1571           {
 1572               if (_majorver > majorver)
 1573                   return false;
 1574               if (_majorver < majorver)
 1575                   return true;
 1576               if (_minorver > minorver)
 1577                   return false;
 1578               if (_minorver < minorver)
 1579                   return true;
 1580               return (_releaseno <= releaseno);
 1581           }
 1582   
 1583           int getActualFiletype()
 1584           {
 1585               return _actualfiletype;
 1586           }
 1587   
 1588           XsbReader(String handle)
 1589           {
 1590               _handle = handle;
 1591               _stringPool = new StringPool(_handle, _name);
 1592           }
 1593   
 1594           void writeRealHeader(String handle, int filetype)
 1595           {
 1596               // hackeroo: if handle contains a "/" it's not relative.
 1597               String resourcename;
 1598   
 1599               if (handle.indexOf('/') >= 0)
 1600                   resourcename = handle + ".xsb";
 1601               else
 1602                   resourcename = _basePackage + handle + ".xsb";
 1603   
 1604               OutputStream rawoutput = getSaverStream(resourcename);
 1605               if (rawoutput == null)
 1606                   throw new SchemaTypeLoaderException("Could not write compiled schema resource " + resourcename, _name, handle, SchemaTypeLoaderException.NOT_WRITEABLE);
 1607   
 1608               _output = new DataOutputStream(rawoutput);
 1609               _handle = handle;
 1610   
 1611               writeInt(DATA_BABE);
 1612               writeShort(MAJOR_VERSION);
 1613               writeShort(MINOR_VERSION);
 1614               writeShort(RELEASE_NUMBER);
 1615               writeShort(filetype);
 1616   
 1617               _stringPool.writeTo(_output);
 1618           }
 1619   
 1620           void readEnd()
 1621           {
 1622               try
 1623               {
 1624                   if (_input != null)
 1625                       _input.close();
 1626               }
 1627               catch (IOException e)
 1628               {
 1629                   // oh, well.
 1630               }
 1631               _input = null;
 1632               _stringPool = null;
 1633               _handle = null;
 1634           }
 1635   
 1636           void writeEnd()
 1637           {
 1638               try
 1639               {
 1640                   if (_output != null)
 1641                   {
 1642                       _output.flush();
 1643                       _output.close();
 1644                   }
 1645               }
 1646               catch (IOException e)
 1647               {
 1648                   throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 1649               }
 1650               _output = null;
 1651               _stringPool = null;
 1652               _handle = null;
 1653           }
 1654   
 1655           int fileTypeFromComponentType(int componentType)
 1656           {
 1657               switch (componentType)
 1658               {
 1659                   case SchemaComponent.TYPE:
 1660                       return SchemaTypeSystemImpl.FILETYPE_SCHEMATYPE;
 1661                   case SchemaComponent.ELEMENT:
 1662                       return SchemaTypeSystemImpl.FILETYPE_SCHEMAELEMENT;
 1663                   case SchemaComponent.ATTRIBUTE:
 1664                       return SchemaTypeSystemImpl.FILETYPE_SCHEMAATTRIBUTE;
 1665                   case SchemaComponent.MODEL_GROUP:
 1666                       return SchemaTypeSystemImpl.FILETYPE_SCHEMAMODELGROUP;
 1667                   case SchemaComponent.ATTRIBUTE_GROUP:
 1668                       return SchemaTypeSystemImpl.FILETYPE_SCHEMAATTRIBUTEGROUP;
 1669                   case SchemaComponent.IDENTITY_CONSTRAINT:
 1670                       return SchemaTypeSystemImpl.FILETYPE_SCHEMAIDENTITYCONSTRAINT;
 1671                   default:
 1672                       throw new IllegalStateException("Unexpected component type");
 1673               }
 1674           }
 1675   
 1676           void writeIndexData()
 1677           {
 1678               // has a handle pool (count, handle/type, handle/type...)
 1679               writeHandlePool(_localHandles);
 1680   
 1681               // then a qname map of global elements (count, qname/handle, qname/handle...)
 1682               writeQNameMap(globalElements());
 1683   
 1684               // qname map of global attributes
 1685               writeQNameMap(globalAttributes());
 1686   
 1687               // qname map of model groups
 1688               writeQNameMap(modelGroups());
 1689   
 1690               // qname map of attribute groups
 1691               writeQNameMap(attributeGroups());
 1692   
 1693               // qname map of identity constraints
 1694               writeQNameMap(identityConstraints());
 1695   
 1696               // qname map of global types
 1697               writeQNameMap(globalTypes());
 1698   
 1699               // qname map of document types, by the qname of the contained element
 1700               writeDocumentTypeMap(documentTypes());
 1701   
 1702               // qname map of attribute types, by the qname of the contained attribute
 1703               writeAttributeTypeMap(attributeTypes());
 1704   
 1705               // all the types by classname
 1706               writeClassnameMap(_typeRefsByClassname);
 1707   
 1708               // all the namespaces
 1709               writeNamespaces(_namespaces);
 1710   
 1711               // VERSION 2.15 and newer below
 1712               writeQNameMap(redefinedGlobalTypes());
 1713               writeQNameMap(redefinedModelGroups());
 1714               writeQNameMap(redefinedAttributeGroups());
 1715               writeAnnotations(annotations());
 1716           }
 1717   
 1718           void writeHandlePool(HandlePool pool)
 1719           {
 1720               writeShort(pool._componentsToHandles.size());
 1721               for (Iterator i = pool._componentsToHandles.keySet().iterator(); i.hasNext(); )
 1722               {
 1723                   SchemaComponent comp = (SchemaComponent)i.next();
 1724                   String handle = (String)pool._componentsToHandles.get(comp);
 1725                   int code = fileTypeFromComponentType(comp.getComponentType());
 1726                   writeString(handle);
 1727                   writeShort(code);
 1728               }
 1729           }
 1730   
 1731           void readHandlePool(HandlePool pool)
 1732           {
 1733               if (pool._handlesToRefs.size() != 0 || pool._started)
 1734                   throw new IllegalStateException("Nonempty handle set before read");
 1735   
 1736               int size = readShort();
 1737               for (int i = 0; i < size; i++)
 1738               {
 1739                   String handle = readString();
 1740                   int code = readShort();
 1741                   Object result;
 1742                   switch (code)
 1743                   {
 1744                       case FILETYPE_SCHEMATYPE:
 1745                           result = new SchemaType.Ref(getTypeSystem(), handle);
 1746                           break;
 1747                       case FILETYPE_SCHEMAELEMENT:
 1748                           result = new SchemaGlobalElement.Ref(getTypeSystem(), handle);
 1749                           break;
 1750                       case FILETYPE_SCHEMAATTRIBUTE:
 1751                           result = new SchemaGlobalAttribute.Ref(getTypeSystem(), handle);
 1752                           break;
 1753                       case FILETYPE_SCHEMAMODELGROUP:
 1754                           result = new SchemaModelGroup.Ref(getTypeSystem(), handle);
 1755                           break;
 1756                       case FILETYPE_SCHEMAATTRIBUTEGROUP:
 1757                           result = new SchemaAttributeGroup.Ref(getTypeSystem(), handle);
 1758                           break;
 1759                       case FILETYPE_SCHEMAIDENTITYCONSTRAINT:
 1760                           result = new SchemaIdentityConstraint.Ref(getTypeSystem(), handle);
 1761                           break;
 1762                       default:
 1763                           throw new SchemaTypeLoaderException("Schema index has an unrecognized entry of type " + code, _name, handle, SchemaTypeLoaderException.UNRECOGNIZED_INDEX_ENTRY);
 1764                   }
 1765                   pool._handlesToRefs.put(handle, result);
 1766               }
 1767           }
 1768   
 1769           int readShort()
 1770           {
 1771               try
 1772               {
 1773                   return _input.readUnsignedShort();
 1774               }
 1775               catch (IOException e)
 1776               {
 1777                   throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 1778               }
 1779           }
 1780   
 1781           void writeShort(int s)
 1782           {
 1783               if (s >= MAX_UNSIGNED_SHORT || s < -1)
 1784                   throw new SchemaTypeLoaderException("Value " + s + " out of range: must fit in a 16-bit unsigned short.", _name, _handle, SchemaTypeLoaderException.INT_TOO_LARGE);
 1785               if (_output != null)
 1786               {
 1787                   try
 1788                   {
 1789                       _output.writeShort(s);
 1790                   }
 1791                   catch (IOException e)
 1792                   {
 1793                       throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 1794                   }
 1795               }
 1796           }
 1797   
 1798           int readInt()
 1799           {
 1800               try
 1801               {
 1802                   return _input.readInt();
 1803               }
 1804               catch (IOException e)
 1805               {
 1806                   throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 1807               }
 1808           }
 1809   
 1810           void writeInt(int i)
 1811           {
 1812               if (_output != null)
 1813               {
 1814                   try
 1815                   {
 1816                       _output.writeInt(i);
 1817                   }
 1818                   catch (IOException e)
 1819                   {
 1820                       throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 1821                   }
 1822               }
 1823           }
 1824   
 1825           String readString()
 1826           {
 1827               return _stringPool.stringForCode(readShort());
 1828           }
 1829   
 1830           void writeString(String str)
 1831           {
 1832               int code = _stringPool.codeForString(str);
 1833               writeShort(code);
 1834           }
 1835   
 1836           QName readQName()
 1837           {
 1838               String namespace = readString();
 1839               String localname = readString();
 1840               if (localname == null)
 1841                   return null;
 1842               return new QName(namespace, localname);
 1843           }
 1844   
 1845           void writeQName(QName qname)
 1846           {
 1847               if (qname == null)
 1848               {
 1849                   writeString(null);
 1850                   writeString(null);
 1851                   return;
 1852               }
 1853               writeString(qname.getNamespaceURI());
 1854               writeString(qname.getLocalPart());
 1855           }
 1856   
 1857           SOAPArrayType readSOAPArrayType()
 1858           {
 1859               QName qName = readQName();
 1860               String dimensions = readString();
 1861               if (qName == null)
 1862                   return null;
 1863               return new SOAPArrayType(qName, dimensions);
 1864           }
 1865   
 1866           void writeSOAPArrayType(SOAPArrayType arrayType)
 1867           {
 1868               if (arrayType == null)
 1869               {
 1870                   writeQName(null);
 1871                   writeString(null);
 1872               }
 1873               else
 1874               {
 1875                   writeQName(arrayType.getQName());
 1876                   writeString(arrayType.soap11DimensionString());
 1877               }
 1878           }
 1879   
 1880           void writeAnnotation(SchemaAnnotation a)
 1881           {
 1882               // Write attributes
 1883               if (a == null)
 1884               {
 1885                   writeInt(-1);
 1886                   return;
 1887               }
 1888               SchemaAnnotation.Attribute[] attributes = a.getAttributes();
 1889               writeInt(attributes.length);
 1890               for (int i = 0; i < attributes.length; i++)
 1891               {
 1892                   QName name = attributes[i].getName();
 1893                   String value = attributes[i].getValue();
 1894                   String valueURI = attributes[i].getValueUri();
 1895                   writeQName(name);
 1896                   writeString(value);
 1897                   writeString(valueURI);
 1898               }
 1899   
 1900               // Write documentation items
 1901               XmlObject[] documentationItems = a.getUserInformation();
 1902               writeInt(documentationItems.length);
 1903               XmlOptions opt = new XmlOptions().setSaveOuter().
 1904                   setSaveAggressiveNamespaces();
 1905               for (int i = 0; i < documentationItems.length; i++)
 1906               {
 1907                   XmlObject doc = documentationItems[i];
 1908                   writeString(doc.xmlText(opt));
 1909               }
 1910   
 1911               // Write application info items
 1912               XmlObject[] appInfoItems = a.getApplicationInformation();
 1913               writeInt(appInfoItems.length);
 1914               for (int i = 0; i < appInfoItems.length; i++)
 1915               {
 1916                   XmlObject doc = appInfoItems[i];
 1917                   writeString(doc.xmlText(opt));
 1918               }
 1919           }
 1920   
 1921           SchemaAnnotation readAnnotation(SchemaContainer c)
 1922           {
 1923               if (!atLeast(2, 19, 0))
 1924                   return null; // no annotations for this version of the file
 1925               // Read attributes
 1926               int n = readInt();
 1927               if (n == -1)
 1928                   return null;
 1929               SchemaAnnotation.Attribute[] attributes =
 1930                   new SchemaAnnotation.Attribute[n];
 1931               for (int i = 0; i < n; i++)
 1932               {
 1933                   QName name = readQName();
 1934                   String value = readString();
 1935                   String valueUri = null;
 1936                   if (atLeast(2, 24, 0))
 1937                       valueUri = readString();
 1938                   attributes[i] = new SchemaAnnotationImpl.AttributeImpl(name, value, valueUri);
 1939               }
 1940   
 1941               // Read documentation items
 1942               n = readInt();
 1943               String[] docStrings = new String[n];
 1944               for (int i = 0; i <  n; i++)
 1945               {
 1946                   docStrings[i] = readString();
 1947               }
 1948   
 1949               // Read application info items
 1950               n = readInt();
 1951               String[] appInfoStrings = new String[n];
 1952               for (int i = 0; i < n; i++)
 1953               {
 1954                   appInfoStrings[i] = readString();
 1955               }
 1956   
 1957               return new SchemaAnnotationImpl(c, appInfoStrings,
 1958                   docStrings, attributes);
 1959           }
 1960   
 1961           void writeAnnotations(SchemaAnnotation[] anns)
 1962           {
 1963               writeInt(anns.length);
 1964               for (int i = 0; i < anns.length; i++)
 1965                   writeAnnotation(anns[i]);
 1966           }
 1967   
 1968           List readAnnotations()
 1969           {
 1970               int n = readInt();
 1971               List result = new ArrayList(n);
 1972               // BUGBUG(radup)
 1973               SchemaContainer container = getContainerNonNull("");
 1974               for (int i = 0; i < n; i++)
 1975                   result.add(readAnnotation(container));
 1976               return result;
 1977           }
 1978   
 1979           SchemaComponent.Ref readHandle()
 1980           {
 1981               String handle = readString();
 1982               if (handle == null)
 1983                   return null;
 1984   
 1985               if (handle.charAt(0) != '_')
 1986                   return _localHandles.refForHandle(handle);
 1987   
 1988               switch (handle.charAt(2))
 1989               {
 1990                   case 'I': // _BI_ - built-in schema type system
 1991                       SchemaType st = (SchemaType) BuiltinSchemaTypeSystem.get().resolveHandle(handle);
 1992                       if (st != null)
 1993                           return st.getRef();
 1994                       st = (SchemaType) XQuerySchemaTypeSystem.get().resolveHandle(handle);
 1995                       return st.getRef();
 1996                   case 'T': // _XT_ - external type
 1997                       return _linker.findTypeRef(QNameHelper.forPretty(handle, 4));
 1998                   case 'E': // _XE_ - external element
 1999                       return _linker.findElementRef(QNameHelper.forPretty(handle, 4));
 2000                   case 'A': // _XA_ - external attribute
 2001                       return _linker.findAttributeRef(QNameHelper.forPretty(handle, 4));
 2002                   case 'M': // _XM_ - external model group
 2003                       return _linker.findModelGroupRef(QNameHelper.forPretty(handle, 4));
 2004                   case 'N': // _XN_ - external attribute group
 2005                       return _linker.findAttributeGroupRef(QNameHelper.forPretty(handle, 4));
 2006                   case 'D': // _XD_ - external identity constraint
 2007                       return _linker.findIdentityConstraintRef(QNameHelper.forPretty(handle, 4));
 2008                   case 'R': // _XR_ - external ref to attribute's type
 2009                       // deprecated: replaced by _XY_
 2010                       SchemaGlobalAttribute attr = _linker.findAttribute(QNameHelper.forPretty(handle, 4));
 2011                       if (attr == null)
 2012                           throw new SchemaTypeLoaderException("Cannot resolve attribute for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
 2013                       return attr.getType().getRef();
 2014                   case 'S': // _XS_ - external ref to element's type
 2015                       // deprecated: replaced by _XY_
 2016                       SchemaGlobalElement elem = _linker.findElement(QNameHelper.forPretty(handle, 4));
 2017                       if (elem == null)
 2018                           throw new SchemaTypeLoaderException("Cannot resolve element for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
 2019                       return elem.getType().getRef();
 2020                   case 'O': // _XO_ - external ref to document type
 2021                       return _linker.findDocumentTypeRef(QNameHelper.forPretty(handle, 4));
 2022                   case 'Y': // _XY_ - external ref to any possible type
 2023                       SchemaType type = _linker.typeForSignature(handle.substring(4));
 2024                       if (type == null)
 2025                           throw new SchemaTypeLoaderException("Cannot resolve type for handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
 2026                       return type.getRef();
 2027                   default:
 2028                       throw new SchemaTypeLoaderException("Cannot resolve handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
 2029               }
 2030           }
 2031   
 2032           void writeHandle(SchemaComponent comp)
 2033           {
 2034               if (comp == null || comp.getTypeSystem() == getTypeSystem())
 2035               {
 2036                   writeString(_localHandles.handleForComponent(comp));
 2037                   return;
 2038               }
 2039   
 2040               switch (comp.getComponentType())
 2041               {
 2042                   case SchemaComponent.ATTRIBUTE:
 2043                       writeString("_XA_" + QNameHelper.pretty(comp.getName()));
 2044                       return;
 2045                   case SchemaComponent.MODEL_GROUP:
 2046                       writeString("_XM_" + QNameHelper.pretty(comp.getName()));
 2047                       return;
 2048                   case SchemaComponent.ATTRIBUTE_GROUP:
 2049                       writeString("_XN_" + QNameHelper.pretty(comp.getName()));
 2050                       return;
 2051                   case SchemaComponent.ELEMENT:
 2052                       writeString("_XE_" + QNameHelper.pretty(comp.getName()));
 2053                       return;
 2054                   case SchemaComponent.IDENTITY_CONSTRAINT:
 2055                       writeString("_XD_" + QNameHelper.pretty(comp.getName()));
 2056                       return;
 2057                   case SchemaComponent.TYPE:
 2058                       SchemaType type = (SchemaType)comp;
 2059                       if (type.isBuiltinType())
 2060                       {
 2061                           writeString("_BI_" + type.getName().getLocalPart());
 2062                           return;
 2063                       }
 2064   
 2065                       // fix for CR120759 - added output of types _XR_ & _XS_
 2066                       // when an attribute (_XR_) or element (_XS_) declaration
 2067                       // uses ref to refer to an attribute or element in another
 2068                       // schema and the type of that attribute or element
 2069                       // is an anonymous (local) type
 2070                       // kkrouse 02/1/2005: _XR_ and _XS_ refs are replaced by _XY_
 2071                       if (type.getName() != null)
 2072                       {
 2073                           writeString("_XT_" + QNameHelper.pretty(type.getName()));
 2074                       }
 2075                       else if (type.isDocumentType())
 2076                       {
 2077                           // Substitution groups will create document types that
 2078                           // extend from other document types, possibly in
 2079                           // different jars
 2080                           writeString("_XO_" + QNameHelper.pretty(type.getDocumentElementName()));
 2081                       }
 2082                       else
 2083                       {
 2084                           // fix for XMLBEANS-105:
 2085                           // save out the external type reference using the type's signature.
 2086                           writeString("_XY_" + type.toString());
 2087                       }
 2088   
 2089                       return;
 2090   
 2091                   default:
 2092                       assert(false);
 2093                       throw new SchemaTypeLoaderException("Cannot write handle for component " + comp, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE);
 2094               }
 2095           }
 2096   
 2097           SchemaType.Ref readTypeRef()
 2098           {
 2099               return (SchemaType.Ref)readHandle();
 2100           }
 2101   
 2102           void writeType(SchemaType type)
 2103           {
 2104               writeHandle(type);
 2105           }
 2106   
 2107           Map readQNameRefMap()
 2108           {
 2109               Map result = new HashMap();
 2110               int size = readShort();
 2111               for (int i = 0; i < size; i++)
 2112               {
 2113                   QName name = readQName();
 2114                   SchemaComponent.Ref obj = readHandle();
 2115                   result.put(name, obj);
 2116               }
 2117               return result;
 2118           }
 2119   
 2120           List readQNameRefMapAsList(List names)
 2121           {
 2122               int size = readShort();
 2123               List result = new ArrayList(size);
 2124               for (int i = 0; i < size; i++)
 2125               {
 2126                   QName name = readQName();
 2127                   SchemaComponent.Ref obj = readHandle();
 2128                   result.add(obj);
 2129                   names.add(name);
 2130               }
 2131               return result;
 2132           }
 2133   
 2134           void writeQNameMap(SchemaComponent[] components)
 2135           {
 2136               writeShort(components.length);
 2137               for (int i = 0; i < components.length; i++)
 2138               {
 2139                   writeQName(components[i].getName());
 2140                   writeHandle(components[i]);
 2141               }
 2142           }
 2143   
 2144           void writeDocumentTypeMap(SchemaType[] doctypes)
 2145           {
 2146               writeShort(doctypes.length);
 2147               for (int i = 0; i < doctypes.length; i++)
 2148               {
 2149                   writeQName(doctypes[i].getDocumentElementName());
 2150                   writeHandle(doctypes[i]);
 2151               }
 2152           }
 2153   
 2154           void writeAttributeTypeMap(SchemaType[] attrtypes)
 2155           {
 2156               writeShort(attrtypes.length);
 2157               for (int i = 0; i < attrtypes.length; i++)
 2158               {
 2159                   writeQName(attrtypes[i].getAttributeTypeAttributeName());
 2160                   writeHandle(attrtypes[i]);
 2161               }
 2162           }
 2163   
 2164           SchemaType.Ref[] readTypeRefArray()
 2165           {
 2166               int size = readShort();
 2167               SchemaType.Ref[] result = new SchemaType.Ref[size];
 2168               for (int i = 0; i < size; i++)
 2169               {
 2170                   result[i] = readTypeRef();
 2171               }
 2172               return result;
 2173           }
 2174   
 2175           void writeTypeArray(SchemaType[] array)
 2176           {
 2177               writeShort(array.length);
 2178               for (int i = 0; i < array.length; i++)
 2179               {
 2180                   writeHandle(array[i]);
 2181               }
 2182           }
 2183   
 2184           Map readClassnameRefMap()
 2185           {
 2186               Map result = new HashMap();
 2187               int size = readShort();
 2188               for (int i = 0; i < size; i++)
 2189               {
 2190                   String name = readString();
 2191                   SchemaComponent.Ref obj = readHandle();
 2192                   result.put(name, obj);
 2193               }
 2194               return result;
 2195           }
 2196   
 2197           void writeClassnameMap(Map typesByClass)
 2198           {
 2199               writeShort(typesByClass.size());
 2200               for (Iterator i = typesByClass.keySet().iterator(); i.hasNext(); )
 2201               {
 2202                   String className = (String)i.next();
 2203                   writeString(className);
 2204                   writeHandle(((SchemaType.Ref)typesByClass.get(className)).get());
 2205               }
 2206           }
 2207   
 2208           Set readNamespaces()
 2209           {
 2210               Set result = new HashSet();
 2211               int size = readShort();
 2212               for (int i = 0; i < size; i++)
 2213               {
 2214                   String ns = readString();
 2215                   result.add(ns);
 2216               }
 2217               return result;
 2218           }
 2219   
 2220           void writeNamespaces(Set namespaces)
 2221           {
 2222               writeShort(namespaces.size());
 2223               for (Iterator i = namespaces.iterator(); i.hasNext(); )
 2224               {
 2225                   String ns = (String)i.next();
 2226                   writeString(ns);
 2227               }
 2228           }
 2229   
 2230           OutputStream getSaverStream(String name)
 2231           {
 2232               try
 2233               {
 2234                   return _filer.createBinaryFile(name);
 2235               }
 2236               catch (IOException e)
 2237               {
 2238                   throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 2239               }
 2240           }
 2241   
 2242           InputStream getLoaderStream(String resourcename)
 2243           {
 2244               return _resourceLoader.getResourceAsStream(resourcename);
 2245           }
 2246   
 2247           void checkContainerNotNull(SchemaContainer container, QName name)
 2248           {
 2249               if (container == null)
 2250               {
 2251                   throw new LinkageError("Loading of resource " + _name + '.' + _handle +
 2252                       "failed, information from " + _name + ".index.xsb is " +
 2253                       " out of sync (or conflicting index files found)");
 2254               }
 2255           }
 2256   
 2257           /**
 2258            * Finishes loading an element after the header has already been loaded.
 2259            */
 2260           public SchemaGlobalElement finishLoadingElement()
 2261           {
 2262               String handle = null;
 2263               try
 2264               {
 2265                   int particleType = readShort();
 2266                   if (particleType != SchemaParticle.ELEMENT)
 2267                       throw new SchemaTypeLoaderException("Wrong particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
 2268                   int particleFlags = readShort();
 2269                   BigInteger minOccurs = readBigInteger();
 2270                   BigInteger maxOccurs = readBigInteger();
 2271                   QNameSet transitionRules = readQNameSet();
 2272                   QName name = readQName();
 2273                   SchemaContainer container = getContainer(name.getNamespaceURI());
 2274                   checkContainerNotNull(container, name);
 2275                   SchemaGlobalElementImpl impl = new SchemaGlobalElementImpl(container);
 2276                   impl.setParticleType(particleType);
 2277                   impl.setMinOccurs(minOccurs);
 2278                   impl.setMaxOccurs(maxOccurs);
 2279                   impl.setTransitionRules(transitionRules,
 2280                       (particleFlags & FLAG_PART_SKIPPABLE) != 0);
 2281                   impl.setNameAndTypeRef(name, readTypeRef());
 2282                   impl.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null);
 2283                   if (atLeast(2, 16, 0))
 2284                       impl.setDefaultValue(readXmlValueObject());
 2285                   impl.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0);
 2286                   impl.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0,
 2287                       (particleFlags & FLAG_PART_BLOCKREST) != 0,
 2288                       (particleFlags & FLAG_PART_BLOCKSUBST) != 0);
 2289                   impl.setWsdlArrayType(readSOAPArrayType());
 2290                   impl.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0);
 2291                   impl.setAnnotation(readAnnotation(container));
 2292                   impl.setFinal(
 2293                                 (particleFlags & FLAG_PART_FINALEXT) != 0,
 2294                                 (particleFlags & FLAG_PART_FINALREST) != 0);
 2295   
 2296                   if (atLeast(2, 17, 0))
 2297                       impl.setSubstitutionGroup((SchemaGlobalElement.Ref)readHandle());
 2298   
 2299                   int substGroupCount = readShort();
 2300                   for (int i = 0; i < substGroupCount; i++)
 2301                   {
 2302                       impl.addSubstitutionGroupMember(readQName());
 2303                   }
 2304                   SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()];
 2305   
 2306                   for (int i = 0 ; i < idcs.length ; i++)
 2307                       idcs[i] = (SchemaIdentityConstraint.Ref)readHandle();
 2308   
 2309                   impl.setIdentityConstraints(idcs);
 2310                   impl.setFilename(readString());
 2311                   return impl;
 2312               }
 2313               catch (SchemaTypeLoaderException e)
 2314               {
 2315                   throw e;
 2316               }
 2317               catch (Exception e)
 2318               {
 2319                   throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
 2320               }
 2321               finally
 2322               {
 2323                   readEnd();
 2324               }
 2325           }
 2326   
 2327           public SchemaGlobalAttribute finishLoadingAttribute()
 2328           {
 2329               try
 2330               {
 2331                   QName name = readQName();
 2332                   SchemaContainer container = getContainer(name.getNamespaceURI());
 2333                   checkContainerNotNull(container, name);
 2334                   SchemaGlobalAttributeImpl impl = new SchemaGlobalAttributeImpl(container);
 2335                   loadAttribute(impl, name, container);
 2336                   impl.setFilename(readString());
 2337   
 2338                   return impl;
 2339               }
 2340               catch (SchemaTypeLoaderException e)
 2341               {
 2342                   throw e;
 2343               }
 2344               catch (Exception e)
 2345               {
 2346                   throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
 2347               }
 2348               finally
 2349               {
 2350                   readEnd();
 2351               }
 2352           }
 2353   
 2354           SchemaModelGroup finishLoadingModelGroup()
 2355           {
 2356               QName name = readQName();
 2357               SchemaContainer container = getContainer(name.getNamespaceURI());
 2358               checkContainerNotNull(container, name);
 2359               SchemaModelGroupImpl impl = new SchemaModelGroupImpl(container);
 2360   
 2361               try
 2362               {
 2363                   impl.init(name, readString(), readShort() == 1,
 2364                       atLeast(2, 22, 0) ? readString() : null,
 2365                       atLeast(2, 22, 0) ? readString() : null,
 2366                       atLeast(2, 15, 0) ? readShort() == 1 : false,
 2367                       GroupDocument.Factory.parse( readString() ).getGroup(), readAnnotation(container), null);
 2368                   if (atLeast(2, 21, 0))
 2369                       impl.setFilename(readString());
 2370                   return impl;
 2371               }
 2372               catch (SchemaTypeLoaderException e)
 2373               {
 2374                   throw e;
 2375               }
 2376               catch (Exception e)
 2377               {
 2378                   throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
 2379               }
 2380               finally
 2381               {
 2382                   readEnd();
 2383               }
 2384           }
 2385   
 2386           SchemaIdentityConstraint finishLoadingIdentityConstraint()
 2387           {
 2388               try {
 2389                   QName name = readQName();
 2390                   SchemaContainer container = getContainer(name.getNamespaceURI());
 2391                   checkContainerNotNull(container, name);
 2392                   SchemaIdentityConstraintImpl impl = new SchemaIdentityConstraintImpl(container);
 2393                   impl.setName(name);
 2394                   impl.setConstraintCategory(readShort());
 2395                   impl.setSelector(readString());
 2396                   impl.setAnnotation(readAnnotation(container));
 2397   
 2398                   String[] fields = new String[readShort()];
 2399                   for (int i = 0 ; i < fields.length ; i++)
 2400                       fields[i] = readString();
 2401                   impl.setFields(fields);
 2402   
 2403                   if (impl.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF)
 2404                       impl.setReferencedKey((SchemaIdentityConstraint.Ref)readHandle());
 2405   
 2406                   int mapCount = readShort();
 2407                   Map nsMappings = new HashMap();
 2408                   for (int i = 0 ; i < mapCount ; i++)
 2409                   {
 2410                       String prefix = readString();
 2411                       String uri = readString();
 2412                       nsMappings.put(prefix, uri);
 2413                   }
 2414                   impl.setNSMap(nsMappings);
 2415   
 2416                   if (atLeast(2, 21, 0))
 2417                       impl.setFilename(readString());
 2418   
 2419                   return impl;
 2420               }
 2421               catch (SchemaTypeLoaderException e)
 2422               {
 2423                   throw e;
 2424               }
 2425               catch (Exception e)
 2426               {
 2427                   throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
 2428               }
 2429               finally
 2430               {
 2431                   readEnd();
 2432               }
 2433           }
 2434   
 2435           SchemaAttributeGroup finishLoadingAttributeGroup()
 2436           {
 2437               QName name = readQName();
 2438               SchemaContainer container = getContainer(name.getNamespaceURI());
 2439               checkContainerNotNull(container, name);
 2440               SchemaAttributeGroupImpl impl = new SchemaAttributeGroupImpl(container);
 2441   
 2442               try
 2443               {
 2444                   impl.init( name, readString(), readShort() == 1,
 2445                       atLeast(2, 22, 0) ? readString() : null,
 2446                       atLeast(2, 15, 0) ? readShort() == 1 : false,
 2447                       AttributeGroupDocument.Factory.parse( readString() ).getAttributeGroup(),
 2448                       readAnnotation(container), null);
 2449                   if (atLeast(2, 21, 0))
 2450                       impl.setFilename(readString());
 2451                   return impl;
 2452               }
 2453               catch (SchemaTypeLoaderException e)
 2454               {
 2455                   throw e;
 2456               }
 2457               catch (Exception e)
 2458               {
 2459                   throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
 2460               }
 2461               finally
 2462               {
 2463                   readEnd();
 2464               }
 2465           }
 2466   
 2467           public SchemaType finishLoadingType()
 2468           {
 2469               try
 2470               {
 2471                   SchemaContainer cNonNull = getContainerNonNull(""); //HACKHACK
 2472                   SchemaTypeImpl impl = new SchemaTypeImpl(cNonNull, true);
 2473                   impl.setName(readQName());
 2474                   impl.setOuterSchemaTypeRef(readTypeRef());
 2475                   impl.setBaseDepth(readShort());
 2476                   impl.setBaseTypeRef(readTypeRef());
 2477                   impl.setDerivationType(readShort());
 2478                   impl.setAnnotation(readAnnotation(null));
 2479   
 2480                   switch (readShort())
 2481                   {
 2482                       case FIELD_GLOBAL:
 2483                           impl.setContainerFieldRef(readHandle());
 2484                           break;
 2485                       case FIELD_LOCALATTR:
 2486                           impl.setContainerFieldIndex((short)1, readShort());
 2487                           break;
 2488                       case FIELD_LOCALELT:
 2489                           impl.setContainerFieldIndex((short)2, readShort());
 2490                           break;
 2491                   }
 2492                   // TODO (radup) find the right solution here
 2493                   String jn = readString();
 2494                   impl.setFullJavaName(jn == null ? "" : jn);
 2495                   jn = readString();
 2496                   impl.setFullJavaImplName(jn == null? "" : jn);
 2497   
 2498                   impl.setAnonymousTypeRefs(readTypeRefArray());
 2499   
 2500                   impl.setAnonymousUnionMemberOrdinal(readShort());
 2501   
 2502                   int flags;
 2503                   flags = readInt();
 2504   
 2505   
 2506                   boolean isComplexType = ((flags & FLAG_SIMPLE_TYPE) == 0);
 2507                   impl.setCompiled((flags & FLAG_COMPILED) != 0);
 2508                   impl.setDocumentType((flags & FLAG_DOCUMENT_TYPE) != 0);
 2509                   impl.setAttributeType((flags & FLAG_ATTRIBUTE_TYPE) != 0);
 2510                   impl.setSimpleType(!isComplexType);
 2511   
 2512                   int complexVariety = SchemaType.NOT_COMPLEX_TYPE;
 2513                   if (isComplexType)
 2514                   {
 2515                       impl.setAbstractFinal((flags & FLAG_ABSTRACT) != 0,
 2516                           (flags & FLAG_FINAL_EXT) != 0,
 2517                           (flags & FLAG_FINAL_REST) != 0,
 2518                           (flags & FLAG_FINAL_LIST) != 0,
 2519                           (flags & FLAG_FINAL_UNION) != 0);
 2520                       impl.setBlock((flags & FLAG_BLOCK_EXT) != 0,
 2521                           (flags & FLAG_BLOCK_REST) != 0);
 2522   
 2523                       impl.setOrderSensitive((flags & FLAG_ORDER_SENSITIVE) != 0);
 2524                       complexVariety = readShort();
 2525                       impl.setComplexTypeVariety(complexVariety);
 2526   
 2527                       if (atLeast(2, 23, 0))
 2528                           impl.setContentBasedOnTypeRef(readTypeRef());
 2529   
 2530                       // Attribute Model Table
 2531                       SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl();
 2532   
 2533                       int attrCount = readShort();
 2534                       for (int i = 0; i < attrCount; i++)
 2535                           attrModel.addAttribute(readAttributeData());
 2536   
 2537                       attrModel.setWildcardSet(readQNameSet());
 2538                       attrModel.setWildcardProcess(readShort());
 2539   
 2540                       // Attribute Property Table
 2541                       Map attrProperties = new LinkedHashMap();
 2542                       int attrPropCount = readShort();
 2543                       for (int i = 0; i < attrPropCount; i++)
 2544                       {
 2545                           SchemaProperty prop = readPropertyData();
 2546                           if (!prop.isAttribute())
 2547                               throw new SchemaTypeLoaderException("Attribute property " + i + " is not an attribute", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE);
 2548                           attrProperties.put(prop.getName(), prop);
 2549                       }
 2550   
 2551                       SchemaParticle contentModel = null;
 2552                       Map elemProperties = null;
 2553                       int isAll = 0;
 2554   
 2555                       if (complexVariety == SchemaType.ELEMENT_CONTENT || complexVariety == SchemaType.MIXED_CONTENT)
 2556                       {
 2557                           // Content Model Tree
 2558                           isAll = readShort();
 2559                           SchemaParticle[] parts = readParticleArray();
 2560                           if (parts.length == 1)
 2561                               contentModel = parts[0];
 2562                           else if (parts.length == 0)
 2563                               contentModel = null;
 2564                           else
 2565                               throw new SchemaTypeLoaderException("Content model not well-formed", _name, _handle, SchemaTypeLoaderException.MALFORMED_CONTENT_MODEL);
 2566   
 2567                           // Element Property Table
 2568   
 2569                           elemProperties = new LinkedHashMap();
 2570                           int elemPropCount = readShort();
 2571                           for (int i = 0; i < elemPropCount; i++)
 2572                           {
 2573                               SchemaProperty prop = readPropertyData();
 2574                               if (prop.isAttribute())
 2575                                   throw new SchemaTypeLoaderException("Element property " + i + " is not an element", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE);
 2576                               elemProperties.put(prop.getName(), prop);
 2577                           }
 2578                       }
 2579   
 2580                       impl.setContentModel(contentModel, attrModel, elemProperties, attrProperties, isAll == 1);
 2581                       StscComplexTypeResolver.WildcardResult wcElt = StscComplexTypeResolver.summarizeEltWildcards(contentModel);
 2582                       StscComplexTypeResolver.WildcardResult wcAttr = StscComplexTypeResolver.summarizeAttrWildcards(attrModel);
 2583                       impl.setWildcardSummary(wcElt.typedWildcards, wcElt.hasWildcards, wcAttr.typedWildcards, wcAttr.hasWildcards);
 2584                   }
 2585   
 2586                   if (!isComplexType || complexVariety == SchemaType.SIMPLE_CONTENT)
 2587                   {
 2588                       int simpleVariety = readShort();
 2589                       impl.setSimpleTypeVariety(simpleVariety);
 2590   
 2591                       boolean isStringEnum = ((flags & FLAG_STRINGENUM) != 0);
 2592   
 2593                       impl.setOrdered((flags & FLAG_ORDERED) != 0 ? SchemaType.UNORDERED : ((flags & FLAG_TOTAL_ORDER) != 0 ? SchemaType.TOTAL_ORDER : SchemaType.PARTIAL_ORDER));
 2594                       impl.setBounded((flags & FLAG_BOUNDED) != 0);
 2595                       impl.setFinite((flags & FLAG_FINITE) != 0);
 2596                       impl.setNumeric((flags & FLAG_NUMERIC) != 0);
 2597                       impl.setUnionOfLists((flags & FLAG_UNION_OF_LISTS) != 0);
 2598                       impl.setSimpleFinal((flags & FLAG_FINAL_REST) != 0,
 2599                           (flags & FLAG_FINAL_LIST) != 0,
 2600                           (flags & FLAG_FINAL_UNION) != 0);
 2601   
 2602                       XmlValueRef[] facets = new XmlValueRef[SchemaType.LAST_FACET + 1];
 2603                       boolean[] fixedFacets = new boolean[SchemaType.LAST_FACET + 1];
 2604                       int facetCount = readShort();
 2605                       for (int i = 0; i < facetCount; i++)
 2606                       {
 2607                           int facetCode = readShort();
 2608                           facets[facetCode] = readXmlValueObject();
 2609                           fixedFacets[facetCode] = (readShort() == 1);
 2610                       }
 2611                       impl.setBasicFacets(facets, fixedFacets);
 2612   
 2613                       impl.setWhiteSpaceRule(readShort());
 2614   
 2615                       impl.setPatternFacet((flags & FLAG_HAS_PATTERN) != 0);
 2616   
 2617                       int patternCount = readShort();
 2618                       org.apache.xmlbeans.impl.regex.RegularExpression[] patterns = new org.apache.xmlbeans.impl.regex.RegularExpression[patternCount];
 2619                       for (int i = 0; i < patternCount; i++)
 2620                       {
 2621                           patterns[i] = new org.apache.xmlbeans.impl.regex.RegularExpression(readString(), "X");
 2622                       }
 2623                       impl.setPatterns(patterns);
 2624   
 2625                       int enumCount = readShort();
 2626                       XmlValueRef[] enumValues = new XmlValueRef[enumCount];
 2627                       for (int i = 0; i < enumCount; i++)
 2628                       {
 2629                           enumValues[i] = readXmlValueObject();
 2630                       }
 2631                       impl.setEnumerationValues(enumCount == 0 ? null : enumValues);
 2632   
 2633                       impl.setBaseEnumTypeRef(readTypeRef());
 2634                       if (isStringEnum)
 2635                       {
 2636                           int seCount = readShort();
 2637                           SchemaStringEnumEntry[] entries = new SchemaStringEnumEntry[seCount];
 2638                           for (int i = 0; i < seCount; i++)
 2639                           {
 2640                               entries[i] = new SchemaStringEnumEntryImpl(readString(), readShort(), readString());
 2641                           }
 2642                           impl.setStringEnumEntries(entries);
 2643                       }
 2644   
 2645                       switch (simpleVariety)
 2646                       {
 2647                           case SchemaType.ATOMIC:
 2648                               impl.setPrimitiveTypeRef(readTypeRef());
 2649                               impl.setDecimalSize(readInt());
 2650                               break;
 2651   
 2652                           case SchemaType.LIST:
 2653                               impl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef());
 2654                               impl.setListItemTypeRef(readTypeRef());
 2655                               break;
 2656   
 2657                           case SchemaType.UNION:
 2658                               impl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef());
 2659                               impl.setUnionMemberTypeRefs(readTypeRefArray());
 2660                               break;
 2661   
 2662                           default:
 2663                               throw new SchemaTypeLoaderException("Simple type does not have a recognized variety", _name, _handle, SchemaTypeLoaderException.WRONG_SIMPLE_VARIETY);
 2664                       }
 2665                   }
 2666   
 2667                   impl.setFilename(readString());
 2668                   // Set the container for global, attribute or document types
 2669                   if (impl.getName() != null)
 2670                   {
 2671                       SchemaContainer container = getContainer(impl.getName().getNamespaceURI());
 2672                       checkContainerNotNull(container, impl.getName());
 2673                       impl.setContainer(container);
 2674                   }
 2675                   else if (impl.isDocumentType())
 2676                   {
 2677                       QName name = impl.getDocumentElementName();
 2678                       if (name != null)
 2679                       {
 2680                           SchemaContainer container = getContainer(name.getNamespaceURI());
 2681                           checkContainerNotNull(container, name);
 2682                           impl.setContainer(container);
 2683                       }
 2684                   }
 2685                   else if (impl.isAttributeType())
 2686                   {
 2687                       QName name = impl.getAttributeTypeAttributeName();
 2688                       if (name != null)
 2689                       {
 2690                           SchemaContainer container = getContainer(name.getNamespaceURI());
 2691                           checkContainerNotNull(container, name);
 2692                           impl.setContainer(container);
 2693                       }
 2694                   }
 2695   
 2696                   return impl;
 2697               }
 2698               catch (SchemaTypeLoaderException e)
 2699               {
 2700                   throw e;
 2701               }
 2702               catch (Exception e)
 2703               {
 2704                   throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e);
 2705               }
 2706               finally
 2707               {
 2708                   readEnd();
 2709               }
 2710           }
 2711   
 2712           void writeTypeData(SchemaType type)
 2713           {
 2714               writeQName(type.getName());
 2715               writeType(type.getOuterType());
 2716               writeShort(((SchemaTypeImpl)type).getBaseDepth());
 2717               writeType(type.getBaseType());
 2718               writeShort(type.getDerivationType());
 2719               writeAnnotation(type.getAnnotation());
 2720               if (type.getContainerField() == null)
 2721               {
 2722                   writeShort(FIELD_NONE);
 2723               }
 2724               else if (type.getOuterType().isAttributeType() || type.getOuterType().isDocumentType())
 2725               {
 2726                   writeShort(FIELD_GLOBAL);
 2727                   writeHandle((SchemaComponent)type.getContainerField());
 2728               }
 2729               else if (type.getContainerField().isAttribute())
 2730               {
 2731                   writeShort(FIELD_LOCALATTR);
 2732                   writeShort(((SchemaTypeImpl)type.getOuterType()).getIndexForLocalAttribute((SchemaLocalAttribute)type.getContainerField()));
 2733               }
 2734               else
 2735               {
 2736                   writeShort(FIELD_LOCALELT);
 2737                   writeShort(((SchemaTypeImpl)type.getOuterType()).getIndexForLocalElement((SchemaLocalElement)type.getContainerField()));
 2738               }
 2739               writeString(type.getFullJavaName());
 2740               writeString(type.getFullJavaImplName());
 2741               writeTypeArray(type.getAnonymousTypes());
 2742               writeShort(type.getAnonymousUnionMemberOrdinal());
 2743   
 2744               int flags = 0;
 2745               if (type.isSimpleType())
 2746                   flags |= FLAG_SIMPLE_TYPE;
 2747               if (type.isDocumentType())
 2748                   flags |= FLAG_DOCUMENT_TYPE;
 2749               if (type.isAttributeType())
 2750                   flags |= FLAG_ATTRIBUTE_TYPE;
 2751               if (type.ordered() != SchemaType.UNORDERED)
 2752                   flags |= FLAG_ORDERED;
 2753               if (type.ordered() == SchemaType.TOTAL_ORDER)
 2754                   flags |= FLAG_TOTAL_ORDER;
 2755               if (type.isBounded())
 2756                   flags |= FLAG_BOUNDED;
 2757               if (type.isFinite())
 2758                   flags |= FLAG_FINITE;
 2759               if (type.isNumeric())
 2760                   flags |= FLAG_NUMERIC;
 2761               if (type.hasStringEnumValues())
 2762                   flags |= FLAG_STRINGENUM;
 2763               if (((SchemaTypeImpl)type).isUnionOfLists())
 2764                   flags |= FLAG_UNION_OF_LISTS;
 2765               if (type.hasPatternFacet())
 2766                   flags |= FLAG_HAS_PATTERN;
 2767               if (type.isOrderSensitive())
 2768                   flags |= FLAG_ORDER_SENSITIVE;
 2769   
 2770               if (type.blockExtension())
 2771                   flags |= FLAG_BLOCK_EXT;
 2772               if (type.blockRestriction())
 2773                   flags |= FLAG_BLOCK_REST;
 2774               if (type.finalExtension())
 2775                   flags |= FLAG_FINAL_EXT;
 2776               if (type.finalRestriction())
 2777                   flags |= FLAG_FINAL_EXT;
 2778               if (type.finalList())
 2779                   flags |= FLAG_FINAL_LIST;
 2780               if (type.finalUnion())
 2781                   flags |= FLAG_FINAL_UNION;
 2782               if (type.isAbstract())
 2783                   flags |= FLAG_ABSTRACT;
 2784   
 2785               writeInt(flags);
 2786   
 2787               if (!type.isSimpleType())
 2788               {
 2789                   writeShort(type.getContentType());
 2790   
 2791                   writeType(type.getContentBasedOnType());
 2792   
 2793                   // Attribute Model Table
 2794                   SchemaAttributeModel attrModel = type.getAttributeModel();
 2795                   SchemaLocalAttribute[] attrs = attrModel.getAttributes();
 2796   
 2797                   writeShort(attrs.length);
 2798                   for (int i = 0; i < attrs.length; i++)
 2799                       writeAttributeData(attrs[i]);
 2800   
 2801                   writeQNameSet(attrModel.getWildcardSet());
 2802                   writeShort(attrModel.getWildcardProcess());
 2803   
 2804                   // Attribute Property Table
 2805                   SchemaProperty[] attrProperties = type.getAttributeProperties();
 2806                   writeShort(attrProperties.length);
 2807                   for (int i = 0; i < attrProperties.length; i++)
 2808                       writePropertyData(attrProperties[i]);
 2809   
 2810                   if (type.getContentType() == SchemaType.ELEMENT_CONTENT ||
 2811                       type.getContentType() == SchemaType.MIXED_CONTENT)
 2812                   {
 2813                       // Content Model Tree
 2814                       writeShort(type.hasAllContent() ? 1 : 0);
 2815                       SchemaParticle[] parts;
 2816                       if (type.getContentModel() != null)
 2817                           parts = new SchemaParticle[] { type.getContentModel() };
 2818                       else
 2819                           parts = new SchemaParticle[0];
 2820   
 2821                       writeParticleArray(parts);
 2822   
 2823                       // Element Property Table
 2824                       SchemaProperty[] eltProperties = type.getElementProperties();
 2825                       writeShort(eltProperties.length);
 2826                       for (int i = 0; i < eltProperties.length; i++)
 2827                           writePropertyData(eltProperties[i]);
 2828                   }
 2829               }
 2830   
 2831               if (type.isSimpleType() || type.getContentType() == SchemaType.SIMPLE_CONTENT)
 2832               {
 2833                   writeShort(type.getSimpleVariety());
 2834   
 2835                   int facetCount = 0;
 2836                   for (int i = 0; i <= SchemaType.LAST_FACET; i++)
 2837                       if (type.getFacet(i) != null)
 2838                           facetCount++;
 2839                   writeShort(facetCount);
 2840                   for (int i = 0; i <= SchemaType.LAST_FACET; i++)
 2841                   {
 2842                       XmlAnySimpleType facet = type.getFacet(i);
 2843                       if (facet != null)
 2844                       {
 2845                           writeShort(i);
 2846                           writeXmlValueObject(facet);
 2847                           writeShort(type.isFacetFixed(i) ? 1 : 0);
 2848                       }
 2849                   }
 2850   
 2851                   writeShort(type.getWhiteSpaceRule());
 2852   
 2853                   org.apache.xmlbeans.impl.regex.RegularExpression[] patterns = ((SchemaTypeImpl)type).getPatternExpressions();
 2854                   writeShort(patterns.length);
 2855                   for (int i = 0; i < patterns.length; i++)
 2856                       writeString(patterns[i].getPattern());
 2857   
 2858                   XmlAnySimpleType[] enumValues = type.getEnumerationValues();
 2859                   if (enumValues == null)
 2860                       writeShort(0);
 2861                   else
 2862                   {
 2863                       writeShort(enumValues.length);
 2864                       for (int i = 0; i < enumValues.length; i++)
 2865                           writeXmlValueObject(enumValues[i]);
 2866                   }
 2867   
 2868                   // new for version 2.3
 2869                   writeType(type.getBaseEnumType());
 2870                   if (type.hasStringEnumValues())
 2871                   {
 2872                       SchemaStringEnumEntry[] entries = type.getStringEnumEntries();
 2873                       writeShort(entries.length);
 2874                       for (int i = 0; i < entries.length; i++)
 2875                       {
 2876                           writeString(entries[i].getString());
 2877                           writeShort(entries[i].getIntValue());
 2878                           writeString(entries[i].getEnumName());
 2879                       }
 2880                   }
 2881   
 2882                   switch (type.getSimpleVariety())
 2883                   {
 2884                       case SchemaType.ATOMIC:
 2885                           writeType(type.getPrimitiveType());
 2886                           writeInt(type.getDecimalSize());
 2887                           break;
 2888   
 2889                       case SchemaType.LIST:
 2890                           writeType(type.getListItemType());
 2891                           break;
 2892   
 2893                       case SchemaType.UNION:
 2894                           writeTypeArray(type.getUnionMemberTypes());
 2895                           break;
 2896                   }
 2897               }
 2898   
 2899               writeString(type.getSourceName());
 2900           }
 2901   
 2902           void readExtensionsList()
 2903           {
 2904               int count = readShort();
 2905               assert count == 0;
 2906   
 2907               for (int i = 0; i < count; i++)
 2908               {
 2909                   readString();
 2910                   readString();
 2911                   readString();
 2912               }
 2913           }
 2914   
 2915           SchemaLocalAttribute readAttributeData()
 2916           {
 2917               SchemaLocalAttributeImpl result = new SchemaLocalAttributeImpl();
 2918               loadAttribute(result, readQName(), null);
 2919               return result;
 2920           }
 2921   
 2922   
 2923           void loadAttribute(SchemaLocalAttributeImpl result, QName name, SchemaContainer container)
 2924           {
 2925               // name, type, use, deftext, defval, fixed, soaparraytype, annotation
 2926               result.init(name, readTypeRef(), readShort(), readString(), null, atLeast(2, 16, 0) ? readXmlValueObject() : null, readShort() == 1, readSOAPArrayType(), readAnnotation(container), null);
 2927           }
 2928   
 2929           void writeAttributeData(SchemaLocalAttribute attr)
 2930           {
 2931               writeQName(attr.getName());
 2932               writeType(attr.getType());
 2933               writeShort(attr.getUse());
 2934               writeString(attr.getDefaultText());
 2935               writeXmlValueObject(attr.getDefaultValue());
 2936               writeShort(attr.isFixed() ? 1 : 0);
 2937               writeSOAPArrayType(((SchemaWSDLArrayType)attr).getWSDLArrayType());
 2938               writeAnnotation(attr.getAnnotation());
 2939           }
 2940   
 2941           void writeIdConstraintData(SchemaIdentityConstraint idc)
 2942           {
 2943               writeQName(idc.getName());
 2944               writeShort(idc.getConstraintCategory());
 2945               writeString(idc.getSelector());
 2946               writeAnnotation(idc.getAnnotation());
 2947   
 2948               String[] fields = idc.getFields();
 2949               writeShort(fields.length);
 2950               for (int i = 0 ; i < fields.length ; i++)
 2951                   writeString(fields[i]);
 2952   
 2953   
 2954               if (idc.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF)
 2955                   writeHandle(idc.getReferencedKey());
 2956   
 2957               Set mappings = idc.getNSMap().entrySet();
 2958               writeShort(mappings.size());
 2959               for (Iterator it = mappings.iterator() ; it.hasNext() ; ) {
 2960                   Map.Entry e = (Map.Entry)it.next();
 2961                   String prefix = (String)e.getKey();
 2962                   String uri = (String)e.getValue();
 2963   
 2964                   writeString(prefix);
 2965                   writeString(uri);
 2966               }
 2967               writeString(idc.getSourceName());
 2968           }
 2969   
 2970           SchemaParticle[] readParticleArray()
 2971           {
 2972               SchemaParticle[] result = new SchemaParticle[readShort()];
 2973               for (int i = 0; i < result.length; i++)
 2974                   result[i] = readParticleData();
 2975               return result;
 2976           }
 2977   
 2978           void writeParticleArray(SchemaParticle[] spa)
 2979           {
 2980               writeShort(spa.length);
 2981               for (int i = 0; i < spa.length; i++)
 2982                   writeParticleData(spa[i]);
 2983           }
 2984   
 2985           SchemaParticle readParticleData()
 2986           {
 2987               int particleType = readShort();
 2988               SchemaParticleImpl result;
 2989               if (particleType != SchemaParticle.ELEMENT)
 2990                   result = new SchemaParticleImpl();
 2991               else
 2992                   result = new SchemaLocalElementImpl();
 2993               loadParticle(result, particleType);
 2994               return result;
 2995           }
 2996   
 2997           void loadParticle(SchemaParticleImpl result, int particleType)
 2998           {
 2999               int particleFlags = readShort();
 3000   
 3001               result.setParticleType(particleType);
 3002               result.setMinOccurs(readBigInteger());
 3003               result.setMaxOccurs(readBigInteger());
 3004   
 3005               result.setTransitionRules(readQNameSet(),
 3006                                         (particleFlags & FLAG_PART_SKIPPABLE) != 0);
 3007   
 3008               switch (particleType)
 3009               {
 3010                   case SchemaParticle.WILDCARD:
 3011                       result.setWildcardSet(readQNameSet());
 3012                       result.setWildcardProcess(readShort());
 3013                       break;
 3014   
 3015                   case SchemaParticle.ELEMENT:
 3016                       SchemaLocalElementImpl lresult = (SchemaLocalElementImpl)result;
 3017                       lresult.setNameAndTypeRef(readQName(), readTypeRef());
 3018                       lresult.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null);
 3019                       if (atLeast(2, 16, 0))
 3020                           lresult.setDefaultValue(readXmlValueObject());
 3021                       lresult.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0);
 3022                       lresult.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0,
 3023                                        (particleFlags & FLAG_PART_BLOCKREST) != 0,
 3024                                        (particleFlags & FLAG_PART_BLOCKSUBST) != 0);
 3025                       lresult.setWsdlArrayType(readSOAPArrayType());
 3026                       lresult.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0);
 3027                       lresult.setAnnotation(readAnnotation(null));
 3028   
 3029                       SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()];
 3030   
 3031                       for (int i = 0 ; i < idcs.length ; i++)
 3032                           idcs[i] = (SchemaIdentityConstraint.Ref)readHandle();
 3033   
 3034                       lresult.setIdentityConstraints(idcs);
 3035   
 3036                       break;
 3037   
 3038                   case SchemaParticle.ALL:
 3039                   case SchemaParticle.SEQUENCE:
 3040                   case SchemaParticle.CHOICE:
 3041                       result.setParticleChildren(readParticleArray());
 3042                       break;
 3043   
 3044                   default:
 3045                       throw new SchemaTypeLoaderException("Unrecognized particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
 3046               }
 3047           }
 3048   
 3049           void writeParticleData(SchemaParticle part)
 3050           {
 3051               writeShort(part.getParticleType());
 3052               short flags = 0;
 3053               if (part.isSkippable())
 3054                   flags |= FLAG_PART_SKIPPABLE;
 3055               if (part.getParticleType() == SchemaParticle.ELEMENT)
 3056               {
 3057                   SchemaLocalElement lpart = (SchemaLocalElement)part;
 3058                   if (lpart.isFixed())
 3059                       flags |= FLAG_PART_FIXED;
 3060                   if (lpart.isNillable())
 3061                       flags |= FLAG_PART_NILLABLE;
 3062                   if (lpart.blockExtension())
 3063                       flags |= FLAG_PART_BLOCKEXT;
 3064                   if (lpart.blockRestriction())
 3065                       flags |= FLAG_PART_BLOCKREST;
 3066                   if (lpart.blockSubstitution())
 3067                       flags |= FLAG_PART_BLOCKSUBST;
 3068                   if (lpart.isAbstract())
 3069                       flags |= FLAG_PART_ABSTRACT;
 3070   
 3071                   if (lpart instanceof SchemaGlobalElement)
 3072                   {
 3073                       SchemaGlobalElement gpart = (SchemaGlobalElement)lpart;
 3074                       if (gpart.finalExtension())
 3075                           flags |= FLAG_PART_FINALEXT;
 3076                       if (gpart.finalRestriction())
 3077                           flags |= FLAG_PART_FINALREST;
 3078                   }
 3079               }
 3080               writeShort(flags);
 3081               writeBigInteger(part.getMinOccurs());
 3082               writeBigInteger(part.getMaxOccurs());
 3083               writeQNameSet(part.acceptedStartNames());
 3084   
 3085               switch (part.getParticleType())
 3086               {
 3087                   case SchemaParticle.WILDCARD:
 3088                       writeQNameSet(part.getWildcardSet());
 3089                       writeShort(part.getWildcardProcess());
 3090                       break;
 3091   
 3092                   case SchemaParticle.ELEMENT:
 3093                       SchemaLocalElement lpart = (SchemaLocalElement)part;
 3094                       writeQName(lpart.getName());
 3095                       writeType(lpart.getType());
 3096                       writeString(lpart.getDefaultText());
 3097                       writeXmlValueObject(lpart.getDefaultValue());
 3098                       writeSOAPArrayType(((SchemaWSDLArrayType)lpart).getWSDLArrayType());
 3099                       writeAnnotation(lpart.getAnnotation());
 3100                       if (lpart instanceof SchemaGlobalElement)
 3101                       {
 3102                           SchemaGlobalElement gpart = (SchemaGlobalElement)lpart;
 3103   
 3104                           writeHandle(gpart.substitutionGroup());
 3105   
 3106                           QName[] substGroupMembers = gpart.substitutionGroupMembers();
 3107                           writeShort(substGroupMembers.length);
 3108                           for (int i = 0; i < substGroupMembers.length; i++)
 3109                               writeQName(substGroupMembers[i]);
 3110                       }
 3111   
 3112                       SchemaIdentityConstraint[] idcs = lpart.getIdentityConstraints();
 3113   
 3114                       writeShort(idcs.length);
 3115                       for (int i = 0 ; i < idcs.length ; i++)
 3116                           writeHandle(idcs[i]);
 3117   
 3118                       break;
 3119   
 3120                   case SchemaParticle.ALL:
 3121                   case SchemaParticle.SEQUENCE:
 3122                   case SchemaParticle.CHOICE:
 3123                       writeParticleArray(part.getParticleChildren());
 3124                       break;
 3125   
 3126                   default:
 3127                       throw new SchemaTypeLoaderException("Unrecognized particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE);
 3128               }
 3129           }
 3130   
 3131           SchemaProperty readPropertyData()
 3132           {
 3133               SchemaPropertyImpl prop = new SchemaPropertyImpl();
 3134               prop.setName(readQName());
 3135               prop.setTypeRef(readTypeRef());
 3136               int propflags = readShort();
 3137               prop.setAttribute((propflags & FLAG_PROP_ISATTR) != 0);
 3138               prop.setContainerTypeRef(readTypeRef());
 3139               prop.setMinOccurs(readBigInteger());
 3140               prop.setMaxOccurs(readBigInteger());
 3141               prop.setNillable(readShort());
 3142               prop.setDefault(readShort());
 3143               prop.setFixed(readShort());
 3144               prop.setDefaultText(readString());
 3145   
 3146               prop.setJavaPropertyName(readString());
 3147               prop.setJavaTypeCode(readShort());
 3148               prop.setExtendsJava(readTypeRef(),
 3149                       (propflags & FLAG_PROP_JAVASINGLETON) != 0,
 3150                       (propflags & FLAG_PROP_JAVAOPTIONAL) != 0,
 3151                       (propflags & FLAG_PROP_JAVAARRAY) != 0);
 3152               if (atMost(2, 19, 0))
 3153                   prop.setJavaSetterDelimiter(readQNameSet());
 3154               if (atLeast(2, 16, 0))
 3155                   prop.setDefaultValue(readXmlValueObject());
 3156   
 3157               if (!prop.isAttribute() && atLeast(2, 17, 0))
 3158               {
 3159                   int size = readShort();
 3160                   LinkedHashSet qnames = new LinkedHashSet(size);
 3161                   for (int i = 0 ; i < size ; i++)
 3162                       qnames.add(readQName());
 3163                   prop.setAcceptedNames(qnames);
 3164               }
 3165               prop.setImmutable();
 3166               return prop;
 3167           }
 3168   
 3169           void writePropertyData(SchemaProperty prop)
 3170           {
 3171               writeQName(prop.getName());
 3172               writeType(prop.getType());
 3173               writeShort((prop.isAttribute() ? FLAG_PROP_ISATTR : 0) |
 3174                          (prop.extendsJavaSingleton() ? FLAG_PROP_JAVASINGLETON : 0) |
 3175                          (prop.extendsJavaOption() ? FLAG_PROP_JAVAOPTIONAL : 0) |
 3176                          (prop.extendsJavaArray() ? FLAG_PROP_JAVAARRAY : 0));
 3177               writeType(prop.getContainerType());
 3178               writeBigInteger(prop.getMinOccurs());
 3179               writeBigInteger(prop.getMaxOccurs());
 3180               writeShort(prop.hasNillable());
 3181               writeShort(prop.hasDefault());
 3182               writeShort(prop.hasFixed());
 3183               writeString(prop.getDefaultText());
 3184   
 3185               writeString(prop.getJavaPropertyName());
 3186               writeShort(prop.getJavaTypeCode());
 3187               writeType(prop.javaBasedOnType());
 3188               writeXmlValueObject(prop.getDefaultValue());
 3189   
 3190               if (! prop.isAttribute())
 3191               {
 3192                   QName[] names = prop.acceptedNames();
 3193                   writeShort(names.length);
 3194                   for (int i = 0 ; i < names.length ; i++)
 3195                       writeQName(names[i]);
 3196               }
 3197           }
 3198   
 3199           void writeModelGroupData(SchemaModelGroup grp)
 3200           {
 3201               SchemaModelGroupImpl impl = (SchemaModelGroupImpl)grp;
 3202               writeQName(impl.getName());
 3203               writeString(impl.getTargetNamespace());
 3204               writeShort(impl.getChameleonNamespace() != null ? 1 : 0);
 3205               writeString(impl.getElemFormDefault()); // new for version 2.22
 3206               writeString(impl.getAttFormDefault()); // new for version 2.22
 3207               writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
 3208               writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
 3209               writeAnnotation(impl.getAnnotation());
 3210               writeString(impl.getSourceName());
 3211           }
 3212   
 3213           void writeAttributeGroupData(SchemaAttributeGroup grp)
 3214           {
 3215               SchemaAttributeGroupImpl impl = (SchemaAttributeGroupImpl)grp;
 3216               writeQName(impl.getName());
 3217               writeString(impl.getTargetNamespace());
 3218               writeShort(impl.getChameleonNamespace() != null ? 1 : 0);
 3219               writeString(impl.getFormDefault()); // new for version 2.22
 3220               writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15
 3221               writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter()));
 3222               writeAnnotation(impl.getAnnotation());
 3223               writeString(impl.getSourceName());
 3224           }
 3225   
 3226           XmlValueRef readXmlValueObject()
 3227           {
 3228               SchemaType.Ref typeref = readTypeRef();
 3229               if (typeref == null)
 3230                   return null;
 3231               int btc = readShort();
 3232               switch (btc)
 3233               {
 3234                   default:
 3235                       assert(false);
 3236                   case 0:
 3237                       return new XmlValueRef(typeref, null);
 3238                   case 0xFFFF:
 3239                       {
 3240                           int size = readShort();
 3241                           List values = new ArrayList();
 3242                           writeShort(values.size());
 3243                           for (int i = 0; i < size; i++)
 3244                           {
 3245                               values.add(readXmlValueObject());
 3246                           }
 3247                           return new XmlValueRef(typeref, values);
 3248                       }
 3249   
 3250   
 3251                   case SchemaType.BTC_ANY_SIMPLE:
 3252                   case SchemaType.BTC_ANY_URI:
 3253                   case SchemaType.BTC_STRING:
 3254                   case SchemaType.BTC_DURATION:
 3255                   case SchemaType.BTC_DATE_TIME:
 3256                   case SchemaType.BTC_TIME:
 3257                   case SchemaType.BTC_DATE:
 3258                   case SchemaType.BTC_G_YEAR_MONTH:
 3259                   case SchemaType.BTC_G_YEAR:
 3260                   case SchemaType.BTC_G_MONTH_DAY:
 3261                   case SchemaType.BTC_G_DAY:
 3262                   case SchemaType.BTC_G_MONTH:
 3263                   case SchemaType.BTC_DECIMAL:
 3264                   case SchemaType.BTC_BOOLEAN:
 3265                       return new XmlValueRef(typeref, readString());
 3266   
 3267                   case SchemaType.BTC_BASE_64_BINARY:
 3268                   case SchemaType.BTC_HEX_BINARY:
 3269                       return new XmlValueRef(typeref, readByteArray());
 3270   
 3271                   case SchemaType.BTC_QNAME:
 3272                   case SchemaType.BTC_NOTATION:
 3273                       return new XmlValueRef(typeref, readQName());
 3274   
 3275                   case SchemaType.BTC_FLOAT:
 3276                   case SchemaType.BTC_DOUBLE:
 3277                       return new XmlValueRef(typeref, new Double(readDouble()));
 3278               }
 3279           }
 3280   
 3281           void writeXmlValueObject(XmlAnySimpleType value)
 3282           {
 3283               SchemaType type = value == null ? null : value.schemaType();
 3284               writeType(type);
 3285               if (type == null)
 3286                   return;
 3287   
 3288               SchemaType iType = ((SimpleValue)value).instanceType();
 3289               if (iType == null)
 3290               {
 3291                   writeShort(0);
 3292               }
 3293               else if (iType.getSimpleVariety() == SchemaType.LIST)
 3294               {
 3295                   writeShort(-1);
 3296                   List values = ((XmlObjectBase)value).xgetListValue();
 3297                   writeShort(values.size());
 3298                   for (Iterator i = values.iterator(); i.hasNext(); )
 3299                   {
 3300                       writeXmlValueObject((XmlAnySimpleType)i.next());
 3301                   }
 3302               }
 3303               else
 3304               {
 3305                   int btc = iType.getPrimitiveType().getBuiltinTypeCode();
 3306                   writeShort(btc);
 3307                   switch (btc)
 3308                   {
 3309                       case SchemaType.BTC_ANY_SIMPLE:
 3310                       case SchemaType.BTC_ANY_URI:
 3311                       case SchemaType.BTC_STRING:
 3312                       case SchemaType.BTC_DURATION:
 3313                       case SchemaType.BTC_DATE_TIME:
 3314                       case SchemaType.BTC_TIME:
 3315                       case SchemaType.BTC_DATE:
 3316                       case SchemaType.BTC_G_YEAR_MONTH:
 3317                       case SchemaType.BTC_G_YEAR:
 3318                       case SchemaType.BTC_G_MONTH_DAY:
 3319                       case SchemaType.BTC_G_DAY:
 3320                       case SchemaType.BTC_G_MONTH:
 3321                       case SchemaType.BTC_DECIMAL:
 3322                       case SchemaType.BTC_BOOLEAN:
 3323                           writeString(value.getStringValue());
 3324                           break;
 3325   
 3326                       case SchemaType.BTC_BASE_64_BINARY:
 3327                       case SchemaType.BTC_HEX_BINARY:
 3328                           writeByteArray(((SimpleValue)value).getByteArrayValue());
 3329                           break;
 3330   
 3331                       case SchemaType.BTC_QNAME:
 3332                       case SchemaType.BTC_NOTATION:
 3333                           writeQName(((SimpleValue)value).getQNameValue());
 3334                           break;
 3335   
 3336                       case SchemaType.BTC_FLOAT:
 3337                           writeDouble(((SimpleValue)value).getFloatValue());
 3338                           break;
 3339   
 3340                       case SchemaType.BTC_DOUBLE:
 3341                           writeDouble(((SimpleValue)value).getDoubleValue());
 3342                           break;
 3343                   }
 3344               }
 3345           }
 3346   
 3347           double readDouble()
 3348           {
 3349               try
 3350               {
 3351                   return _input.readDouble();
 3352               }
 3353               catch (IOException e)
 3354               {
 3355                   throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 3356               }
 3357           }
 3358   
 3359           void writeDouble(double d)
 3360           {
 3361               if (_output != null)
 3362               {
 3363                   try
 3364                   {
 3365                       _output.writeDouble(d);
 3366                   }
 3367                   catch (IOException e)
 3368                   {
 3369                       throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 3370                   }
 3371               }
 3372           }
 3373   
 3374           QNameSet readQNameSet()
 3375           {
 3376               int flag = readShort();
 3377   
 3378               Set uriSet = new HashSet();
 3379               int uriCount = readShort();
 3380               for (int i = 0; i < uriCount; i++)
 3381                   uriSet.add(readString());
 3382   
 3383               Set qnameSet1 = new HashSet();
 3384               int qncount1 = readShort();
 3385               for (int i = 0; i < qncount1; i++)
 3386                   qnameSet1.add(readQName());
 3387   
 3388               Set qnameSet2 = new HashSet();
 3389               int qncount2 = readShort();
 3390               for (int i = 0; i < qncount2; i++)
 3391                   qnameSet2.add(readQName());
 3392   
 3393               if (flag == 1)
 3394                   return QNameSet.forSets(uriSet, null, qnameSet1, qnameSet2);
 3395               else
 3396                   return QNameSet.forSets(null, uriSet, qnameSet2, qnameSet1);
 3397           }
 3398   
 3399           void writeQNameSet(QNameSet set)
 3400           {
 3401               boolean invert = (set.excludedURIs() != null);
 3402               writeShort(invert ? 1 : 0);
 3403   
 3404               Set uriSet = invert ? set.excludedURIs() : set.includedURIs();
 3405               writeShort(uriSet.size());
 3406               for (Iterator i = uriSet.iterator(); i.hasNext(); )
 3407                   writeString((String)i.next());
 3408   
 3409               Set qnameSet1 = invert ? set.excludedQNamesInIncludedURIs() : set.includedQNamesInExcludedURIs();
 3410               writeShort(qnameSet1.size());
 3411               for (Iterator i = qnameSet1.iterator(); i.hasNext(); )
 3412                   writeQName((QName)i.next());
 3413   
 3414               Set qnameSet2 = invert ? set.includedQNamesInExcludedURIs() : set.excludedQNamesInIncludedURIs();
 3415               writeShort(qnameSet2.size());
 3416               for (Iterator i = qnameSet2.iterator(); i.hasNext(); )
 3417                   writeQName((QName)i.next());
 3418           }
 3419   
 3420           byte[] readByteArray()
 3421           {
 3422               try
 3423               {
 3424                   int len = _input.readShort();
 3425                   byte[] result = new byte[len];
 3426                   _input.readFully(result);
 3427                   return result;
 3428               }
 3429               catch (IOException e)
 3430               {
 3431                   throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 3432               }
 3433           }
 3434   
 3435           void writeByteArray(byte[] ba)
 3436           {
 3437               try
 3438               {
 3439                   writeShort(ba.length);
 3440                   if (_output != null)
 3441                       _output.write(ba);
 3442               }
 3443               catch (IOException e)
 3444               {
 3445                   throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION);
 3446               }
 3447           }
 3448   
 3449           BigInteger readBigInteger()
 3450           {
 3451               byte[] result = readByteArray();
 3452               if (result.length == 0)
 3453                   return null;
 3454               if (result.length == 1 && result[0] == 0)
 3455                   return BigInteger.ZERO;
 3456               if (result.length == 1 && result[0] == 1)
 3457                   return BigInteger.ONE;
 3458               return new BigInteger(result);
 3459           }
 3460   
 3461           void writeBigInteger(BigInteger bi)
 3462           {
 3463               if (bi == null)
 3464               {
 3465                   writeShort(0);
 3466               }
 3467               else if (bi.signum() == 0)
 3468               {
 3469                   writeByteArray(SINGLE_ZERO_BYTE);
 3470               }
 3471               else
 3472               {
 3473                   writeByteArray(bi.toByteArray());
 3474               }
 3475           }
 3476   
 3477       }
 3478   
 3479       static final byte[] SINGLE_ZERO_BYTE = new byte[] { (byte)0 };
 3480   
 3481       public SchemaType typeForHandle(String handle)
 3482       {
 3483           synchronized (_resolvedHandles)
 3484           {
 3485               return (SchemaType)_resolvedHandles.get(handle);
 3486           }
 3487       }
 3488   
 3489       public SchemaType typeForClassname(String classname)
 3490       {
 3491           SchemaType.Ref ref = (SchemaType.Ref)_typeRefsByClassname.get(classname);
 3492           return (ref != null) ? ref.get() : null;
 3493       }
 3494   
 3495       public SchemaComponent resolveHandle(String handle)
 3496       {
 3497           SchemaComponent result;
 3498   
 3499           synchronized (_resolvedHandles)
 3500           {
 3501               result = (SchemaComponent)_resolvedHandles.get(handle);
 3502           }
 3503           if (result == null)
 3504           {
 3505               XsbReader reader = new XsbReader(handle, 0xFFFF);
 3506               int filetype = reader.getActualFiletype();
 3507               switch (filetype)
 3508               {
 3509                   case FILETYPE_SCHEMATYPE:
 3510                       XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving type for handle " + handle, 0);
 3511                       result = reader.finishLoadingType();
 3512                       break;
 3513                   case FILETYPE_SCHEMAELEMENT:
 3514                       XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving element for handle " + handle, 0);
 3515                       result = reader.finishLoadingElement();
 3516                       break;
 3517                   case FILETYPE_SCHEMAATTRIBUTE:
 3518                       XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving attribute for handle " + handle, 0);
 3519                       result = reader.finishLoadingAttribute();
 3520                       break;
 3521                   case FILETYPE_SCHEMAMODELGROUP:
 3522                       XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving model group for handle " + handle, 0);
 3523                       result = reader.finishLoadingModelGroup();
 3524                       break;
 3525                   case FILETYPE_SCHEMAATTRIBUTEGROUP:
 3526                       XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving attribute group for handle " + handle, 0);
 3527                       result = reader.finishLoadingAttributeGroup();
 3528                       break;
 3529                   case FILETYPE_SCHEMAIDENTITYCONSTRAINT:
 3530                       XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving id constraint for handle " + handle, 0);
 3531                       result = reader.finishLoadingIdentityConstraint();
 3532                       break;
 3533                   default:
 3534                       throw new IllegalStateException("Illegal handle type");
 3535               }
 3536   
 3537               synchronized (_resolvedHandles)
 3538               {
 3539                   if (!_resolvedHandles.containsKey(handle))
 3540                       _resolvedHandles.put(handle, result);
 3541                   else
 3542                       result = (SchemaComponent)_resolvedHandles.get(handle);
 3543               }
 3544           }
 3545           return result;
 3546       }
 3547   
 3548       private final Map _resolvedHandles = new HashMap();
 3549       private boolean _allNonGroupHandlesResolved = false;
 3550   
 3551       public void resolve()
 3552       {
 3553           XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolve called type system " + _name, 0);
 3554           if (_allNonGroupHandlesResolved)
 3555               return;
 3556   
 3557           XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving all handles for type system " + _name, 1);
 3558   
 3559           List refs = new ArrayList();
 3560           refs.addAll(_globalElements.values());
 3561           refs.addAll(_globalAttributes.values());
 3562           refs.addAll(_globalTypes.values());
 3563           refs.addAll(_documentTypes.values());
 3564           refs.addAll(_attributeTypes.values());
 3565           refs.addAll(_identityConstraints.values());
 3566   
 3567           for (Iterator i = refs.iterator(); i.hasNext(); )
 3568           {
 3569               SchemaComponent.Ref ref = (SchemaComponent.Ref)i.next();
 3570               ref.getComponent(); // Forces ref to be resolved
 3571           }
 3572   
 3573           XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished resolving type system " + _name, -1);
 3574           _allNonGroupHandlesResolved = true;
 3575       }
 3576   
 3577   
 3578       public boolean isNamespaceDefined(String namespace)
 3579       {
 3580           return _namespaces.contains(namespace);
 3581       }
 3582   
 3583       public SchemaType.Ref findTypeRef(QName name)
 3584       {
 3585           return (SchemaType.Ref)_globalTypes.get(name);
 3586       }
 3587   
 3588       public SchemaType.Ref findDocumentTypeRef(QName name)
 3589       {
 3590           return (SchemaType.Ref)_documentTypes.get(name);
 3591       }
 3592   
 3593       public SchemaType.Ref findAttributeTypeRef(QName name)
 3594       {
 3595           return (SchemaType.Ref)_attributeTypes.get(name);
 3596       }
 3597   
 3598       public SchemaGlobalElement.Ref findElementRef(QName name)
 3599       {
 3600           return (SchemaGlobalElement.Ref)_globalElements.get(name);
 3601       }
 3602   
 3603       public SchemaGlobalAttribute.Ref findAttributeRef(QName name)
 3604       {
 3605           return (SchemaGlobalAttribute.Ref)_globalAttributes.get(name);
 3606       }
 3607   
 3608       public SchemaModelGroup.Ref findModelGroupRef(QName name)
 3609       {
 3610           return (SchemaModelGroup.Ref)_modelGroups.get(name);
 3611       }
 3612   
 3613       public SchemaAttributeGroup.Ref findAttributeGroupRef(QName name)
 3614       {
 3615           return (SchemaAttributeGroup.Ref)_attributeGroups.get(name);
 3616       }
 3617   
 3618       public SchemaIdentityConstraint.Ref findIdentityConstraintRef(QName name)
 3619       {
 3620           return (SchemaIdentityConstraint.Ref)_identityConstraints.get(name);
 3621       }
 3622   
 3623       public SchemaType[] globalTypes()
 3624       {
 3625           if (_globalTypes.isEmpty())
 3626               return EMPTY_ST_ARRAY;
 3627   
 3628           SchemaType[] result = new SchemaType[_globalTypes.size()];
 3629           int j = 0;
 3630           for (Iterator i = _globalTypes.values().iterator(); i.hasNext(); j++)
 3631               result[j] = ((SchemaType.Ref)i.next()).get();
 3632           return result;
 3633       }
 3634   
 3635       public SchemaType[] redefinedGlobalTypes()
 3636       {
 3637           if (_redefinedGlobalTypes == null || _redefinedGlobalTypes.isEmpty())
 3638               return EMPTY_ST_ARRAY;
 3639   
 3640           SchemaType[] result = new SchemaType[_redefinedGlobalTypes.size()];
 3641           int j = 0;
 3642           for (Iterator i = _redefinedGlobalTypes.iterator(); i.hasNext(); j++)
 3643               result[j] = ((SchemaType.Ref)i.next()).get();
 3644           return result;
 3645       }
 3646   
 3647       public InputStream getSourceAsStream(String sourceName)
 3648       {
 3649           if (!sourceName.startsWith("/"))
 3650               sourceName = "/" + sourceName;
 3651   
 3652           return _resourceLoader.getResourceAsStream("schema" + METADATA_PACKAGE_GEN + "/src" + sourceName);
 3653       }
 3654   
 3655       SchemaContainer[] containers()
 3656       {
 3657           SchemaContainer[] result = new SchemaContainer[_containers.size()];
 3658           int j = 0;
 3659           for (Iterator i = _containers.values().iterator(); i.hasNext(); j++)
 3660               result[j] = (SchemaContainer) i.next();
 3661           return result;
 3662       }
 3663   
 3664       public SchemaType[] documentTypes()
 3665       {
 3666           if (_documentTypes.isEmpty())
 3667               return EMPTY_ST_ARRAY;
 3668   
 3669           SchemaType[] result = new SchemaType[_documentTypes.size()];
 3670           int j = 0;
 3671           for (Iterator i = _documentTypes.values().iterator(); i.hasNext(); j++)
 3672               result[j] = ((SchemaType.Ref)i.next()).get();
 3673           return result;
 3674       }
 3675   
 3676       public SchemaType[] attributeTypes()
 3677       {
 3678           if (_attributeTypes.isEmpty())
 3679               return EMPTY_ST_ARRAY;
 3680   
 3681           SchemaType[] result = new SchemaType[_attributeTypes.size()];
 3682           int j = 0;
 3683           for (Iterator i = _attributeTypes.values().iterator(); i.hasNext(); j++)
 3684               result[j] = ((SchemaType.Ref)i.next()).get();
 3685           return result;
 3686       }
 3687   
 3688       public SchemaGlobalElement[] globalElements()
 3689       {
 3690           if (_globalElements.isEmpty())
 3691               return EMPTY_GE_ARRAY;
 3692   
 3693           SchemaGlobalElement[] result = new SchemaGlobalElement[_globalElements.size()];
 3694           int j = 0;
 3695           for (Iterator i = _globalElements.values().iterator(); i.hasNext(); j++)
 3696               result[j] = ((SchemaGlobalElement.Ref)i.next()).get();
 3697           return result;
 3698       }
 3699   
 3700       public SchemaGlobalAttribute[] globalAttributes()
 3701       {
 3702           if (_globalAttributes.isEmpty())
 3703               return EMPTY_GA_ARRAY;
 3704   
 3705           SchemaGlobalAttribute[] result = new SchemaGlobalAttribute[_globalAttributes.size()];
 3706           int j = 0;
 3707           for (Iterator i = _globalAttributes.values().iterator(); i.hasNext(); j++)
 3708               result[j] = ((SchemaGlobalAttribute.Ref)i.next()).get();
 3709           return result;
 3710       }
 3711   
 3712       public SchemaModelGroup[] modelGroups()
 3713       {
 3714           if (_modelGroups.isEmpty())
 3715               return EMPTY_MG_ARRAY;
 3716   
 3717           SchemaModelGroup[] result = new SchemaModelGroup[_modelGroups.size()];
 3718           int j = 0;
 3719           for (Iterator i = _modelGroups.values().iterator(); i.hasNext(); j++)
 3720               result[j] = ((SchemaModelGroup.Ref)i.next()).get();
 3721           return result;
 3722       }
 3723   
 3724       public SchemaModelGroup[] redefinedModelGroups()
 3725       {
 3726           if (_redefinedModelGroups == null || _redefinedModelGroups.isEmpty())
 3727               return EMPTY_MG_ARRAY;
 3728   
 3729           SchemaModelGroup[] result = new SchemaModelGroup[_redefinedModelGroups.size()];
 3730           int j = 0;
 3731           for (Iterator i = _redefinedModelGroups.iterator(); i.hasNext(); j++)
 3732               result[j] = ((SchemaModelGroup.Ref)i.next()).get();
 3733           return result;
 3734       }
 3735   
 3736       public SchemaAttributeGroup[] attributeGroups()
 3737       {
 3738           if (_attributeGroups.isEmpty())
 3739               return EMPTY_AG_ARRAY;
 3740   
 3741           SchemaAttributeGroup[] result = new SchemaAttributeGroup[_attributeGroups.size()];
 3742           int j = 0;
 3743           for (Iterator i = _attributeGroups.values().iterator(); i.hasNext(); j++)
 3744               result[j] = ((SchemaAttributeGroup.Ref)i.next()).get();
 3745           return result;
 3746       }
 3747   
 3748       public SchemaAttributeGroup[] redefinedAttributeGroups()
 3749       {
 3750           if (_redefinedAttributeGroups == null || _redefinedAttributeGroups.isEmpty())
 3751               return EMPTY_AG_ARRAY;
 3752   
 3753           SchemaAttributeGroup[] result = new SchemaAttributeGroup[_redefinedAttributeGroups.size()];
 3754           int j = 0;
 3755           for (Iterator i = _redefinedAttributeGroups.iterator(); i.hasNext(); j++)
 3756               result[j] = ((SchemaAttributeGroup.Ref)i.next()).get();
 3757           return result;
 3758       }
 3759   
 3760       public SchemaAnnotation[] annotations()
 3761       {
 3762           if (_annotations == null || _annotations.isEmpty())
 3763               return EMPTY_ANN_ARRAY;
 3764   
 3765           SchemaAnnotation[] result = new SchemaAnnotation[_annotations.size()];
 3766           result = (SchemaAnnotation[]) _annotations.toArray(result);
 3767           return result;
 3768       }
 3769   
 3770       public SchemaIdentityConstraint[] identityConstraints()
 3771       {
 3772           if (_identityConstraints.isEmpty())
 3773               return EMPTY_IC_ARRAY;
 3774   
 3775           SchemaIdentityConstraint[] result = new SchemaIdentityConstraint[_identityConstraints.size()];
 3776           int j = 0;
 3777           for (Iterator i = _identityConstraints.values().iterator(); i.hasNext(); j++)
 3778               result[j] = ((SchemaIdentityConstraint.Ref)i.next()).get();
 3779           return result;
 3780       }
 3781   
 3782       public ClassLoader getClassLoader()
 3783       {
 3784           return _classloader;
 3785       }
 3786   
 3787       /**
 3788        * Used INTERNALLY ONLY by the code output AFTER the type system has
 3789        * been saved and a handle has been established for each type.
 3790        */
 3791       public String handleForType(SchemaType type)
 3792       {
 3793           return _localHandles.handleForType(type);
 3794       }
 3795   
 3796       public String getName()
 3797       {
 3798           return _name;
 3799       }
 3800   
 3801       public SchemaTypeSystem typeSystemForName(String name)
 3802       {
 3803           if (_name != null && name.equals(_name))
 3804               return this;
 3805           return null;
 3806       }
 3807   }

Home » xmlbeans-2.5.0-src » org.apache.xmlbeans.impl » schema » [javadoc | source]