| /* |
| * The Apache Software License, Version 1.1 |
| * |
| * |
| * Copyright (c) 2003 The Apache Software Foundation. All rights |
| * reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in |
| * the documentation and/or other materials provided with the |
| * distribution. |
| * |
| * 3. The end-user documentation included with the redistribution, |
| * if any, must include the following acknowledgment: |
| * "This product includes software developed by the |
| * Apache Software Foundation (http://www.apache.org/)." |
| * Alternately, this acknowledgment may appear in the software itself, |
| * if and wherever such third-party acknowledgments normally appear. |
| * |
| * 4. The names "Apache" and "Apache Software Foundation" must |
| * not be used to endorse or promote products derived from this |
| * software without prior written permission. For written |
| * permission, please contact apache@apache.org. |
| * |
| * 5. Products derived from this software may not be called "Apache |
| * XMLBeans", nor may "Apache" appear in their name, without prior |
| * written permission of the Apache Software Foundation. |
| * |
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED |
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR |
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT |
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| * SUCH DAMAGE. |
| * ==================================================================== |
| * |
| * This software consists of voluntary contributions made by many |
| * individuals on behalf of the Apache Software Foundation and was |
| * originally based on software copyright (c) 2000-2003 BEA Systems |
| * Inc., <http://www.bea.com/>. For more information on the Apache Software |
| * Foundation, please see <http://www.apache.org/>. |
| */ |
| |
| package org.apache.xmlbeans.impl.schema; |
| |
| import javax.xml.namespace.QName; |
| import org.apache.xmlbeans.impl.common.NameUtil; |
| import org.apache.xmlbeans.impl.common.QNameHelper; |
| import org.apache.xmlbeans.impl.common.XBeanDebug; |
| import org.apache.xmlbeans.impl.common.XmlErrorWatcher; |
| |
| import java.io.InputStream; |
| import java.io.DataInputStream; |
| import java.io.DataOutputStream; |
| import java.io.IOException; |
| import java.io.OutputStream; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.ByteArrayOutputStream; |
| import java.util.*; |
| import java.util.zip.ZipFile; |
| import java.util.zip.ZipEntry; |
| import java.math.BigInteger; |
| |
| |
| import org.apache.xmlbeans.impl.regex.RegularExpression; |
| import org.apache.xmlbeans.impl.util.HexBin; |
| import org.apache.xmlbeans.impl.values.XmlObjectBase; |
| import org.apache.xmlbeans.XmlObject; |
| import org.apache.xmlbeans.XmlException; |
| import org.apache.xmlbeans.XmlOptions; |
| import org.apache.xmlbeans.SchemaGlobalElement; |
| import org.apache.xmlbeans.SchemaComponent; |
| import org.apache.xmlbeans.SchemaType; |
| import org.apache.xmlbeans.SchemaParticle; |
| import org.apache.xmlbeans.SchemaGlobalAttribute; |
| import org.apache.xmlbeans.SchemaModelGroup; |
| import org.apache.xmlbeans.SchemaAttributeGroup; |
| import org.apache.xmlbeans.SchemaAttributeModel; |
| import org.apache.xmlbeans.SchemaTypeLoader; |
| import org.apache.xmlbeans.SchemaProperty; |
| import org.apache.xmlbeans.QNameSet; |
| import org.apache.xmlbeans.SchemaLocalAttribute; |
| import org.apache.xmlbeans.SchemaLocalElement; |
| import org.apache.xmlbeans.XmlAnySimpleType; |
| import org.apache.xmlbeans.SchemaStringEnumEntry; |
| import org.apache.xmlbeans.SchemaTypeSystem; |
| import org.apache.xmlbeans.SchemaIdentityConstraint; |
| import org.apache.xmlbeans.SimpleValue; |
| import org.apache.xmlbeans.SchemaTypeLoaderException; |
| import org.apache.xmlbeans.SchemaField; |
| import org.apache.xmlbeans.soap.SOAPArrayType; |
| import org.apache.xmlbeans.soap.SchemaWSDLArrayType; |
| import com.bea.x2002.x09.xbean.config.ConfigDocument.Config; |
| import com.bea.x2002.x09.xbean.config.ConfigDocument; |
| import org.w3.x2001.xmlSchema.SchemaDocument; |
| import org.w3.x2001.xmlSchema.GroupDocument; |
| import org.w3.x2001.xmlSchema.AttributeGroupDocument; |
| import org.w3.x2001.xmlSchema.SchemaDocument.Schema; |
| |
| public class SchemaTypeSystemImpl extends SchemaTypeLoaderBase implements SchemaTypeSystem |
| { |
| public static final int DATA_BABE = 0xDA7ABABE; |
| public static final int MAJOR_VERSION = 2; // must match == to be compatible |
| public static final int MINOR_VERSION = 18; // must be <= to be compatible |
| public static final int RELEASE_NUMBER = 0; // should be compatible even if < or > |
| |
| public static final int FILETYPE_SCHEMAINDEX = 1; |
| public static final int FILETYPE_SCHEMATYPE = 2; |
| public static final int FILETYPE_SCHEMAELEMENT = 3; |
| public static final int FILETYPE_SCHEMAATTRIBUTE = 4; |
| public static final int FILETYPE_SCHEMAPOINTER = 5; |
| public static final int FILETYPE_SCHEMAMODELGROUP = 6; |
| public static final int FILETYPE_SCHEMAATTRIBUTEGROUP = 7; |
| public static final int FILETYPE_SCHEMAIDENTITYCONSTRAINT = 8; |
| |
| public static final int FLAG_PART_SKIPPABLE = 1; |
| public static final int FLAG_PART_FIXED = 4; |
| public static final int FLAG_PART_NILLABLE = 8; |
| public static final int FLAG_PART_BLOCKEXT = 16; |
| public static final int FLAG_PART_BLOCKREST = 32; |
| public static final int FLAG_PART_BLOCKSUBST = 64; |
| public static final int FLAG_PART_ABSTRACT = 128; |
| public static final int FLAG_PART_FINALEXT = 256; |
| public static final int FLAG_PART_FINALREST = 512; |
| |
| public static final int FLAG_PROP_ISATTR = 1; |
| public static final int FLAG_PROP_JAVASINGLETON = 2; |
| public static final int FLAG_PROP_JAVAOPTIONAL = 4; |
| public static final int FLAG_PROP_JAVAARRAY = 8; |
| |
| public static final int FIELD_NONE = 0; |
| public static final int FIELD_GLOBAL = 1; |
| public static final int FIELD_LOCALATTR = 2; |
| public static final int FIELD_LOCALELT = 3; |
| |
| // type flags |
| static final int FLAG_SIMPLE_TYPE = 0x1; |
| static final int FLAG_DOCUMENT_TYPE = 0x2; |
| static final int FLAG_ORDERED = 0x4; |
| static final int FLAG_BOUNDED = 0x8; |
| static final int FLAG_FINITE = 0x10; |
| static final int FLAG_NUMERIC = 0x20; |
| static final int FLAG_STRINGENUM = 0x40; |
| static final int FLAG_UNION_OF_LISTS = 0x80; |
| static final int FLAG_HAS_PATTERN = 0x100; |
| static final int FLAG_ORDER_SENSITIVE = 0x200; |
| static final int FLAG_TOTAL_ORDER = 0x400; |
| static final int FLAG_COMPILED = 0x800; |
| static final int FLAG_BLOCK_EXT = 0x1000; |
| static final int FLAG_BLOCK_REST = 0x2000; |
| static final int FLAG_FINAL_EXT = 0x4000; |
| static final int FLAG_FINAL_REST = 0x8000; |
| static final int FLAG_FINAL_UNION = 0x10000; |
| static final int FLAG_FINAL_LIST = 0x20000; |
| static final int FLAG_ABSTRACT = 0x40000; |
| static final int FLAG_ATTRIBUTE_TYPE = 0x80000; |
| |
| |
| private static String nameToPathString(String nameForSystem) |
| { |
| nameForSystem = nameForSystem.replace('.', '/'); |
| |
| if (!nameForSystem.endsWith("/") && nameForSystem.length() > 0) |
| nameForSystem = nameForSystem + "/"; |
| |
| return nameForSystem; |
| } |
| |
| public SchemaTypeSystemImpl(Class indexclass) |
| { |
| String fullname = indexclass.getName(); |
| _name = fullname.substring(0, fullname.lastIndexOf('.')); |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Loading type system " + _name, 1); |
| _basePackage = nameToPathString(_name); |
| _classloader = indexclass.getClassLoader(); |
| _linker = SchemaTypeLoaderImpl.build(null, null, _classloader); |
| _resourceLoader = new ClassLoaderResourceLoader(_classloader); |
| initFromHeader(); |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished loading type system " + _name, -1); |
| } |
| |
| private static final Schema[] EMPTY_SCHEMA_ARRAY = new Schema[0]; |
| private static final Config[] EMPTY_CONFIG_ARRAY = new Config[0]; |
| |
| public static SchemaTypeSystemImpl forSchemaXml( |
| XmlObject[] input, SchemaTypeLoader linkTo, XmlOptions options) |
| throws XmlException |
| { |
| options = XmlOptions.maskNull(options); |
| ArrayList schemas = new ArrayList(); |
| ArrayList configs = new ArrayList(); |
| |
| for (int i = 0; i < input.length; i++) |
| { |
| if (input[i] instanceof Schema) |
| schemas.add(input[i]); |
| else if (input[i] instanceof SchemaDocument && ((SchemaDocument)input[i]).getSchema() != null) |
| schemas.add(((SchemaDocument)input[i]).getSchema()); |
| else if (input[i] instanceof Config) |
| configs.add(input[i]); |
| else if (input[i] instanceof ConfigDocument && ((ConfigDocument)input[i]).getConfig() != null) |
| configs.add(((ConfigDocument)input[i]).getConfig()); |
| else |
| throw new XmlException("Thread " + Thread.currentThread().getName() + ": The " + i + "th supplied input is not a schema or a config document: its type is " + input[i].schemaType()); |
| } |
| |
| |
| |
| Collection userErrors = (Collection)options.get(XmlOptions.ERROR_LISTENER); |
| XmlErrorWatcher errorWatcher = new XmlErrorWatcher(userErrors); |
| |
| SchemaTypeSystemImpl stsi = |
| SchemaTypeSystemCompiler.compileImpl( |
| null, (Schema[])schemas.toArray(EMPTY_SCHEMA_ARRAY), |
| (Config[])configs.toArray(EMPTY_CONFIG_ARRAY), linkTo, options, errorWatcher, false, null, null); |
| |
| if (errorWatcher.hasError()) |
| { |
| throw new XmlException(errorWatcher.firstError()); |
| } |
| |
| return stsi; |
| } |
| |
| public static boolean fileContainsTypeSystem(File file, String name) |
| { |
| String indexname = nameToPathString(name) + "index.xsb"; |
| |
| if (file.isDirectory()) |
| { |
| return (new File(file, indexname)).isFile(); |
| } |
| else |
| { |
| ZipFile zipfile = null; |
| try |
| { |
| zipfile = new ZipFile(file); |
| ZipEntry entry = zipfile.getEntry(indexname); |
| return (entry != null && !entry.isDirectory()); |
| } |
| catch (IOException e) |
| { |
| XBeanDebug.log("Problem loading SchemaTypeSystem, zipfilename " + file); |
| XBeanDebug.logException(e); |
| throw new SchemaTypeLoaderException(e.getMessage(), name, "index", SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| finally |
| { |
| if (zipfile != null) |
| try { zipfile.close(); } catch (IOException e) {} |
| } |
| } |
| } |
| |
| public static SchemaTypeSystemImpl forName(String name, ClassLoader loader) |
| { |
| try |
| { |
| Class c = Class.forName(name + "." + SchemaTypeCodePrinter.INDEX_CLASSNAME, true, loader); |
| return (SchemaTypeSystemImpl)c.getField("typeSystem").get(null); |
| } |
| catch (Exception e) |
| { |
| return null; |
| } |
| } |
| |
| public SchemaTypeSystemImpl(ResourceLoader resourceLoader, String name, SchemaTypeLoader linker) |
| { |
| _name = name; |
| _basePackage = nameToPathString(_name); |
| _linker = linker; |
| _resourceLoader = resourceLoader; |
| try |
| { |
| initFromHeader(); |
| } |
| catch (RuntimeException e) |
| { |
| XBeanDebug.logException(e); |
| throw e; |
| } |
| catch (Error e) |
| { |
| XBeanDebug.logException(e); |
| throw e; |
| } |
| } |
| |
| private void initFromHeader() |
| { |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Reading unresolved handles for type system " + _name, 0); |
| XsbReader reader = null; |
| try |
| { |
| // Read the index file, which starts with a header. |
| reader = new XsbReader("index", FILETYPE_SCHEMAINDEX); |
| |
| // has a handle pool (count, handle/type, handle/type...) |
| _localHandles = new HandlePool(); |
| reader.readHandlePool(_localHandles); |
| |
| // then a qname map of global elements (count, qname/handle, qname/handle...) |
| _globalElements = reader.readQNameRefMap(); |
| |
| // qname map of global attributes |
| _globalAttributes = reader.readQNameRefMap(); |
| |
| // qname map of model groups |
| _modelGroups = reader.readQNameRefMap(); |
| |
| // qname map of attribute groups |
| _attributeGroups = reader.readQNameRefMap(); |
| |
| _identityConstraints = reader.readQNameRefMap(); |
| |
| // qname map of global types |
| _globalTypes = reader.readQNameRefMap(); |
| |
| // qname map of document types, by the qname of the contained element |
| _documentTypes = reader.readQNameRefMap(); |
| |
| // qname mape of attribute types, by the qname of the contained attribute |
| _attributeTypes = reader.readQNameRefMap(); |
| |
| // string map of all types, by fully qualified classname |
| _typeRefsByClassname = reader.readClassnameRefMap(); |
| |
| _namespaces = reader.readNamespaces(); |
| |
| // support for redefine, at the end of the file |
| if (reader.atLeast(2, 15, 0)) |
| { |
| _redefinedGlobalTypes = reader.readQNameRefMap(); |
| _redefinedModelGroups = reader.readQNameRefMap(); |
| _redefinedAttributeGroups = reader.readQNameRefMap(); |
| } |
| } |
| finally |
| { |
| if (reader != null) |
| reader.readEnd(); |
| } |
| } |
| |
| void saveIndex() |
| { |
| String handle = "index"; |
| XsbReader saver = new XsbReader(handle); |
| saver.writeIndexData(); |
| saver.writeRealHeader(handle, FILETYPE_SCHEMAINDEX); |
| saver.writeIndexData(); |
| saver.writeEnd(); |
| } |
| |
| void savePointers() |
| { |
| savePointersForComponents(globalElements(), "schema/element/"); |
| savePointersForComponents(globalAttributes(), "schema/attribute/"); |
| savePointersForComponents(modelGroups(), "schema/modelgroup/"); |
| savePointersForComponents(attributeGroups(), "schema/attributegroup/"); |
| savePointersForComponents(globalTypes(), "schema/type/"); |
| savePointersForComponents(identityConstraints(), "schema/identityconstraint/"); |
| savePointersForNamespaces(_namespaces, "schema/namespace/"); |
| savePointersForClassnames(_typeRefsByClassname.keySet(), "schema/javaname/"); |
| savePointersForComponents(redefinedModelGroups(), "schema/redefinedmodelgroup/"); |
| savePointersForComponents(redefinedAttributeGroups(), "schema/redefinedattributegroup/"); |
| savePointersForComponents(redefinedGlobalTypes(), "schema/redefinedtype/"); |
| } |
| |
| void savePointersForComponents(SchemaComponent[] components, String dir) |
| { |
| for (int i = 0; i < components.length; i++) |
| { |
| savePointerFile(dir + QNameHelper.hexsafedir(components[i].getName()), _name); |
| } |
| } |
| |
| void savePointersForClassnames(Set classnames, String dir) |
| { |
| for (Iterator i = classnames.iterator(); i.hasNext(); ) |
| { |
| String classname = (String)i.next(); |
| savePointerFile(dir + classname.replace('.', '/'), _name); |
| } |
| } |
| |
| void savePointersForNamespaces(Set namespaces, String dir) |
| { |
| for (Iterator i = namespaces.iterator(); i.hasNext(); ) |
| { |
| String ns = (String)i.next(); |
| savePointerFile(dir + QNameHelper.hexsafedir(new QName(ns, "xmlns")), _name); |
| } |
| } |
| |
| void savePointerFile(String filename, String name) |
| { |
| XsbReader saver = new XsbReader(filename); |
| saver.writeString(name); |
| saver.writeRealHeader(filename, FILETYPE_SCHEMAPOINTER); |
| saver.writeString(name); |
| saver.writeEnd(); |
| } |
| |
| /** |
| * Only used in the nonbootstrapped case. |
| */ |
| private Map buildTypeRefsByClassname() |
| { |
| List allSeenTypes = new ArrayList(); |
| Map result = new LinkedHashMap(); |
| allSeenTypes.addAll(Arrays.asList(documentTypes())); |
| allSeenTypes.addAll(Arrays.asList(attributeTypes())); |
| allSeenTypes.addAll(Arrays.asList(globalTypes())); |
| |
| // now fully javaize everything deeply. |
| for (int i = 0; i < allSeenTypes.size(); i++) |
| { |
| SchemaType gType = (SchemaType)allSeenTypes.get(i); |
| String className = gType.getFullJavaName(); |
| if (className != null) |
| { |
| result.put(className.replace('$', '.'), gType.getRef()); |
| } |
| allSeenTypes.addAll(Arrays.asList(gType.getAnonymousTypes())); |
| } |
| return result; |
| } |
| |
| private Map buildTypeRefsByClassname(Map typesByClassname) |
| { |
| Map result = new LinkedHashMap(); |
| for (Iterator i = typesByClassname.keySet().iterator(); i.hasNext(); ) |
| { |
| String className = (String)i.next(); |
| result.put(className, ((SchemaType)typesByClassname.get(className)).getRef()); |
| } |
| return result; |
| } |
| |
| private static Map buildComponentRefMap(SchemaComponent[] components) |
| { |
| Map result = new LinkedHashMap(); |
| for (int i = 0; i < components.length; i++) |
| result.put(components[i].getName(), components[i].getComponentRef()); |
| return result; |
| } |
| |
| private static Map buildDocumentMap(SchemaType[] types) |
| { |
| Map result = new LinkedHashMap(); |
| for (int i = 0; i < types.length; i++) |
| result.put(types[i].getDocumentElementName(), types[i].getRef()); |
| return result; |
| } |
| |
| private static Map buildAttributeTypeMap(SchemaType[] types) |
| { |
| Map result = new LinkedHashMap(); |
| for (int i = 0; i < types.length; i++) |
| result.put(types[i].getAttributeTypeAttributeName(), types[i].getRef()); |
| return result; |
| } |
| |
| private static Random _random; |
| private static byte[] _mask = new byte[128 / 8]; |
| |
| /** |
| * Fun, fun. Produce 128 bits of uniqueness randomly. |
| * We used to use SecureRandom, but now we don't because SecureRandom |
| * hits the filesystem and hangs us on a filesystem lock. It also eats |
| * a thread and other expensive resources.. :-). |
| * |
| * We don't really care that non-secure Random() can only do 48 bits of |
| * randomness, since we're certainly not going to be called more than 2^48 |
| * times within our process lifetime. |
| * |
| * Our real concern is that by seeding Random() with the current |
| * time, two users will end up with the same bits if they start a |
| * schema compilation within the same millisecond. That makes the |
| * probability of collision in the real world slightly too high. |
| * We're going to have millions of users, remember? With a million |
| * users, and one-compilation-per-day each, we'd see a collision every |
| * few months. |
| * |
| * So we'll just xor the results of random with our few extra |
| * bits of information computed below to help reduce the probability |
| * of collision by a few decimal places. To collide, you will have had |
| * to have the same amount of free memory, the same user name, timezone, |
| * and country, the same current directory, the same java classpath, |
| * the same operating system and jvm version, and the same choices of |
| * identity hashcodes for a few objects. And be started within the same |
| * millisecond. Or you can collide if you have a cosmic 128-bit mathematical |
| * coincidence. No worries. |
| */ |
| private static synchronized void nextBytes(byte[] result) |
| { |
| if (_random == null) |
| { |
| try |
| { |
| ByteArrayOutputStream baos = new ByteArrayOutputStream(); |
| DataOutputStream daos = new DataOutputStream(baos); |
| |
| // at least 10 bits of unqieueness, right? Maybe even 50 or 60. |
| daos.writeInt(System.identityHashCode(SchemaTypeSystemImpl.class)); |
| String[] props = new String[] { "user.name", "user.dir", "user.timezone", "user.country", "java.class.path", "java.home", "java.vendor", "java.version", "os.version" }; |
| for (int i = 0; i < props.length; i++) |
| { |
| String prop = System.getProperty(props[i]); |
| if (prop != null) |
| { |
| daos.writeUTF(prop); |
| daos.writeInt(System.identityHashCode(prop)); |
| } |
| } |
| daos.writeLong(Runtime.getRuntime().freeMemory()); |
| daos.close(); |
| byte[] bytes = baos.toByteArray(); |
| for (int i = 0; i < bytes.length; i++) |
| { |
| int j = i % _mask.length; |
| _mask[j] *= 21; |
| _mask[j] += i; |
| } |
| } |
| catch (IOException e) |
| { |
| XBeanDebug.logException(e); |
| } |
| |
| _random = new Random(System.currentTimeMillis()); |
| } |
| _random.nextBytes(result); |
| for (int i = 0; i < result.length; i++) |
| { |
| int j = i & _mask.length; |
| result[i] ^= _mask[j]; |
| } |
| } |
| |
| public SchemaTypeSystemImpl(String nameForSystem) |
| { |
| // if we have no name, select a random one |
| if (nameForSystem == null) |
| { |
| // get 128 random bits (that'll be 32 hex digits) |
| byte[] bytes = new byte[128/8]; |
| nextBytes(bytes); |
| nameForSystem = "s" + new String(HexBin.encode(bytes)); |
| } |
| |
| _name = "schema.system." + nameForSystem; |
| _basePackage = nameToPathString(_name); |
| _classloader = null; |
| |
| } |
| |
| public void loadFromBuilder(SchemaGlobalElement[] globalElements, |
| SchemaGlobalAttribute[] globalAttributes, |
| SchemaType[] globalTypes, |
| SchemaType[] documentTypes, |
| SchemaType[] attributeTypes) |
| { |
| assert(_classloader == null); |
| _localHandles = new HandlePool(); |
| _globalElements = buildComponentRefMap(globalElements); |
| _globalAttributes = buildComponentRefMap(globalAttributes); |
| _globalTypes = buildComponentRefMap(globalTypes); |
| _documentTypes = buildDocumentMap(documentTypes); |
| _attributeTypes = buildDocumentMap(attributeTypes); |
| _typeRefsByClassname = buildTypeRefsByClassname(); |
| _namespaces = new HashSet(); |
| } |
| |
| public void loadFromStscState(StscState state) |
| { |
| assert(_classloader == null); |
| _localHandles = new HandlePool(); |
| _globalElements = buildComponentRefMap(state.globalElements()); |
| _globalAttributes = buildComponentRefMap(state.globalAttributes()); |
| _modelGroups = buildComponentRefMap(state.modelGroups()); |
| _redefinedModelGroups = buildComponentRefMap(state.redefinedModelGroups()); |
| _attributeGroups = buildComponentRefMap(state.attributeGroups()); |
| _redefinedAttributeGroups = buildComponentRefMap(state.redefinedAttributeGroups()); |
| _globalTypes = buildComponentRefMap(state.globalTypes()); |
| _redefinedGlobalTypes = buildComponentRefMap(state.redefinedGlobalTypes()); |
| _documentTypes = buildDocumentMap(state.documentTypes()); |
| _attributeTypes = buildAttributeTypeMap(state.attributeTypes()); |
| _typeRefsByClassname = buildTypeRefsByClassname(state.typesByClassname()); |
| _identityConstraints = buildComponentRefMap(state.idConstraints()); |
| _namespaces = new HashSet(Arrays.asList(state.getNamespaces())); |
| } |
| |
| final SchemaTypeSystemImpl getTypeSystem() |
| { |
| return this; |
| } |
| |
| static class StringPool |
| { |
| private List intsToStrings = new ArrayList(); |
| private Map stringsToInts = new HashMap(); |
| private String _handle; |
| private String _name; |
| |
| /** |
| * Constructs an empty StringPool to be filled with strings. |
| */ |
| StringPool(String handle, String name) |
| { |
| _handle = handle; |
| _name = name; |
| intsToStrings.add(null); |
| } |
| |
| int codeForString(String str) |
| { |
| if (str == null) |
| return 0; |
| Integer result = (Integer)stringsToInts.get(str); |
| if (result == null) |
| { |
| result = new Integer(intsToStrings.size()); |
| intsToStrings.add(str); |
| stringsToInts.put(str, result); |
| } |
| return result.intValue(); |
| } |
| |
| String stringForCode(int code) |
| { |
| if (code == 0) |
| return null; |
| return (String)intsToStrings.get(code); |
| } |
| |
| void writeTo(DataOutputStream output) |
| { |
| if (intsToStrings.size() > Short.MAX_VALUE) |
| throw new SchemaTypeLoaderException("Too many strings (" + intsToStrings.size() + ")", _name, _handle, SchemaTypeLoaderException.INT_TOO_LARGE); |
| |
| try |
| { |
| output.writeShort(intsToStrings.size()); |
| Iterator i = intsToStrings.iterator(); |
| for (i.next(); i.hasNext(); ) |
| { |
| String str = (String)i.next(); |
| output.writeUTF(str); |
| } |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| |
| void readFrom(DataInputStream input) |
| { |
| if (intsToStrings.size() != 1 || stringsToInts.size() != 0) |
| throw new IllegalStateException(); |
| |
| try |
| { |
| int size = input.readShort(); |
| for (int i = 1; i < size; i++) |
| { |
| String str = input.readUTF().intern(); |
| int code = codeForString(str); |
| if (code != i) |
| throw new IllegalStateException(); |
| } |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage() == null ? e.getMessage() : "IO Exception", _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| } |
| |
| class HandlePool |
| { |
| private Map _handlesToRefs = new LinkedHashMap(); |
| private Map _componentsToHandles = new LinkedHashMap(); // populated on write |
| private boolean _started; |
| |
| /** |
| * Constructs an empty HandlePool to be populated. |
| */ |
| HandlePool() |
| { |
| } |
| |
| private String addUniqueHandle(SchemaComponent obj, String base) |
| { |
| base = base.toLowerCase(); // we lowercase handles because of case-insensitive Windows filenames!!! |
| String handle = base; |
| for (int index = 2; _handlesToRefs.containsKey(handle); index++) |
| { |
| handle = base + index; |
| } |
| _handlesToRefs.put(handle, obj.getComponentRef()); |
| _componentsToHandles.put(obj, handle); |
| return handle; |
| } |
| |
| String handleForComponent(SchemaComponent comp) |
| { |
| if (comp == null) |
| return null; |
| if (comp.getTypeSystem() != getTypeSystem()) |
| throw new IllegalArgumentException("Cannot supply handles for types from another type system"); |
| if (comp instanceof SchemaType) |
| return handleForType((SchemaType)comp); |
| if (comp instanceof SchemaGlobalElement) |
| return handleForElement((SchemaGlobalElement)comp); |
| if (comp instanceof SchemaGlobalAttribute) |
| return handleForAttribute((SchemaGlobalAttribute)comp); |
| if (comp instanceof SchemaModelGroup) |
| return handleForModelGroup((SchemaModelGroup)comp); |
| if (comp instanceof SchemaAttributeGroup) |
| return handleForAttributeGroup((SchemaAttributeGroup)comp); |
| if (comp instanceof SchemaIdentityConstraint) |
| return handleForIdentityConstraint((SchemaIdentityConstraint)comp); |
| throw new IllegalStateException("Component type cannot have a handle"); |
| } |
| |
| String handleForElement(SchemaGlobalElement element) |
| { |
| if (element == null) |
| return null; |
| if (element.getTypeSystem() != getTypeSystem()) |
| throw new IllegalArgumentException("Cannot supply handles for types from another type system"); |
| String handle = (String)_componentsToHandles.get(element); |
| if (handle == null) |
| handle = addUniqueHandle(element, NameUtil.upperCamelCase(element.getName().getLocalPart()) + "Element"); |
| return handle; |
| } |
| |
| String handleForAttribute(SchemaGlobalAttribute attribute) |
| { |
| if (attribute == null) |
| return null; |
| if (attribute.getTypeSystem() != getTypeSystem()) |
| throw new IllegalArgumentException("Cannot supply handles for types from another type system"); |
| String handle = (String)_componentsToHandles.get(attribute); |
| if (handle == null) |
| handle = addUniqueHandle(attribute, NameUtil.upperCamelCase(attribute.getName().getLocalPart()) + "Attribute"); |
| return handle; |
| } |
| |
| String handleForModelGroup(SchemaModelGroup group) |
| { |
| if (group == null) |
| return null; |
| if (group.getTypeSystem() != getTypeSystem()) |
| throw new IllegalArgumentException("Cannot supply handles for types from another type system"); |
| String handle = (String)_componentsToHandles.get(group); |
| if (handle == null) |
| handle = addUniqueHandle(group, NameUtil.upperCamelCase(group.getName().getLocalPart()) + "ModelGroup"); |
| return handle; |
| } |
| |
| String handleForAttributeGroup(SchemaAttributeGroup group) |
| { |
| if (group == null) |
| return null; |
| if (group.getTypeSystem() != getTypeSystem()) |
| throw new IllegalArgumentException("Cannot supply handles for types from another type system"); |
| String handle = (String)_componentsToHandles.get(group); |
| if (handle == null) |
| handle = addUniqueHandle(group, NameUtil.upperCamelCase(group.getName().getLocalPart()) + "AttributeGroup"); |
| return handle; |
| } |
| |
| String handleForIdentityConstraint(SchemaIdentityConstraint idc) |
| { |
| if (idc == null) |
| return null; |
| if (idc.getTypeSystem() != getTypeSystem()) |
| throw new IllegalArgumentException("Cannot supply handles for types from another type system"); |
| String handle = (String)_componentsToHandles.get(idc); |
| if (handle == null) |
| handle = addUniqueHandle(idc, NameUtil.upperCamelCase(idc.getName().getLocalPart()) + "IdentityConstraint"); |
| return handle; |
| } |
| |
| String handleForType(SchemaType type) |
| { |
| if (type == null) |
| return null; |
| if (type.getTypeSystem() != getTypeSystem()) |
| throw new IllegalArgumentException("Cannot supply handles for types from another type system"); |
| String handle = (String)_componentsToHandles.get(type); |
| if (handle == null) |
| { |
| QName name = type.getName(); |
| String suffix = ""; |
| if (name == null) |
| { |
| if (type.isDocumentType()) |
| { |
| name = type.getDocumentElementName(); |
| suffix = "Doc"; |
| } |
| else if (type.isAttributeType()) |
| { |
| name = type.getAttributeTypeAttributeName(); |
| suffix = "AttrType"; |
| } |
| else if (type.getContainerField() != null) |
| { |
| name = type.getContainerField().getName(); |
| suffix = type.getContainerField().isAttribute() ? "Attr" : "Elem"; |
| } |
| } |
| |
| String baseName; |
| String uniq = Integer.toHexString(type.toString().hashCode() | 0x80000000).substring(4).toUpperCase(); |
| if (name == null) |
| baseName = "Anon" + uniq + "Type"; |
| else |
| baseName = NameUtil.upperCamelCase(name.getLocalPart()) + uniq + suffix + "Type"; |
| |
| handle = addUniqueHandle(type, baseName); |
| } |
| |
| return handle; |
| } |
| |
| SchemaComponent.Ref refForHandle(String handle) |
| { |
| if (handle == null) |
| return null; |
| |
| return (SchemaComponent.Ref)_handlesToRefs.get(handle); |
| } |
| |
| Set getAllHandles() |
| { |
| return _handlesToRefs.keySet(); |
| } |
| |
| void startWriteMode() |
| { |
| _started = true; |
| _componentsToHandles = new LinkedHashMap(); |
| for (Iterator i = _handlesToRefs.keySet().iterator(); i.hasNext(); ) |
| { |
| String handle = (String)i.next(); |
| // System.err.println("Writing preexisting handle " + handle); |
| SchemaComponent comp = ((SchemaComponent.Ref)_handlesToRefs.get(handle)).getComponent(); |
| _componentsToHandles.put(comp, handle); |
| } |
| } |
| |
| } |
| |
| private String _name; |
| private String _basePackage; |
| |
| // classloader is available for sts's that were compiled and loaded, not dynamic ones |
| private ClassLoader _classloader; |
| |
| // the loader for loading .xsb resources |
| private ResourceLoader _resourceLoader; |
| |
| // the following is used to link references during load |
| SchemaTypeLoader _linker; |
| |
| private HandlePool _localHandles; |
| private File _baseSaveDir; |
| |
| // actual type system data, map QNames -> SchemaComponent.Ref |
| private Map _redefinedModelGroups; |
| private Map _redefinedAttributeGroups; |
| private Map _redefinedGlobalTypes; |
| |
| private Map _globalElements; |
| private Map _globalAttributes; |
| private Map _modelGroups; |
| private Map _attributeGroups; |
| private Map _globalTypes; |
| private Map _documentTypes; |
| private Map _attributeTypes; |
| private Map _identityConstraints = Collections.EMPTY_MAP; |
| private Map _typeRefsByClassname = new HashMap(); |
| private Set _namespaces; |
| |
| static private final SchemaType[] EMPTY_ST_ARRAY = new SchemaType[0]; |
| static private final SchemaGlobalElement[] EMPTY_GE_ARRAY = new SchemaGlobalElement[0]; |
| static private final SchemaGlobalAttribute[] EMPTY_GA_ARRAY = new SchemaGlobalAttribute[0]; |
| static private final SchemaModelGroup[] EMPTY_MG_ARRAY = new SchemaModelGroup[0]; |
| static private final SchemaAttributeGroup[] EMPTY_AG_ARRAY = new SchemaAttributeGroup[0]; |
| static private final SchemaIdentityConstraint[] EMPTY_IC_ARRAY = new SchemaIdentityConstraint[0]; |
| |
| public void saveToDirectory(File classDir) |
| { |
| _baseSaveDir = classDir; |
| |
| _localHandles.startWriteMode(); |
| saveTypesRecursively(globalTypes()); |
| saveTypesRecursively(documentTypes()); |
| saveTypesRecursively(attributeTypes()); |
| saveGlobalElements(globalElements()); |
| saveGlobalAttributes(globalAttributes()); |
| saveModelGroups(modelGroups()); |
| saveAttributeGroups(attributeGroups()); |
| saveIdentityConstraints(identityConstraints()); |
| |
| saveTypesRecursively(redefinedGlobalTypes()); |
| saveModelGroups(redefinedModelGroups()); |
| saveAttributeGroups(redefinedAttributeGroups()); |
| |
| saveIndex(); |
| savePointers(); |
| } |
| |
| void saveTypesRecursively(SchemaType[] types) |
| { |
| for (int i = 0; i < types.length; i++) |
| { |
| if (types[i].getTypeSystem() != getTypeSystem()) |
| continue; |
| saveType(types[i]); |
| saveTypesRecursively(types[i].getAnonymousTypes()); |
| } |
| } |
| |
| public void saveGlobalElements(SchemaGlobalElement[] elts) |
| { |
| for (int i = 0; i < elts.length; i++) |
| { |
| saveGlobalElement(elts[i]); |
| } |
| } |
| |
| public void saveGlobalAttributes(SchemaGlobalAttribute[] attrs) |
| { |
| for (int i = 0; i < attrs.length; i++) |
| { |
| saveGlobalAttribute(attrs[i]); |
| } |
| } |
| |
| public void saveModelGroups(SchemaModelGroup[] groups) |
| { |
| for (int i = 0; i < groups.length; i++) |
| { |
| saveModelGroup(groups[i]); |
| } |
| } |
| |
| public void saveAttributeGroups(SchemaAttributeGroup[] groups) |
| { |
| for (int i = 0; i < groups.length; i++) |
| { |
| saveAttributeGroup(groups[i]); |
| } |
| } |
| |
| public void saveIdentityConstraints(SchemaIdentityConstraint[] idcs) |
| { |
| for (int i = 0; i < idcs.length; i++) |
| { |
| saveIdentityConstraint(idcs[i]); |
| } |
| } |
| |
| public void saveGlobalElement(SchemaGlobalElement elt) |
| { |
| String handle = _localHandles.handleForElement(elt); |
| XsbReader saver = new XsbReader(handle); |
| saver.writeParticleData((SchemaParticle)elt); |
| saver.writeString(elt.getSourceName()); |
| saver.writeRealHeader(handle, FILETYPE_SCHEMAELEMENT); |
| saver.writeParticleData((SchemaParticle)elt); |
| saver.writeString(elt.getSourceName()); |
| saver.writeEnd(); |
| } |
| |
| public void saveGlobalAttribute(SchemaGlobalAttribute attr) |
| { |
| String handle = _localHandles.handleForAttribute(attr); |
| XsbReader saver = new XsbReader(handle); |
| saver.writeAttributeData(attr); |
| saver.writeString(attr.getSourceName()); |
| saver.writeRealHeader(handle, FILETYPE_SCHEMAATTRIBUTE); |
| saver.writeAttributeData(attr); |
| saver.writeString(attr.getSourceName()); |
| saver.writeEnd(); |
| } |
| |
| public void saveModelGroup(SchemaModelGroup grp) |
| { |
| String handle = _localHandles.handleForModelGroup(grp); |
| XsbReader saver = new XsbReader(handle); |
| saver.writeModelGroupData(grp); |
| saver.writeRealHeader(handle, FILETYPE_SCHEMAMODELGROUP); |
| saver.writeModelGroupData(grp); |
| saver.writeEnd(); |
| } |
| |
| public void saveAttributeGroup(SchemaAttributeGroup grp) |
| { |
| String handle = _localHandles.handleForAttributeGroup(grp); |
| XsbReader saver = new XsbReader(handle); |
| saver.writeAttributeGroupData(grp); |
| saver.writeRealHeader(handle, FILETYPE_SCHEMAATTRIBUTEGROUP); |
| saver.writeAttributeGroupData(grp); |
| saver.writeEnd(); |
| } |
| |
| public void saveIdentityConstraint(SchemaIdentityConstraint idc) |
| { |
| String handle = _localHandles.handleForIdentityConstraint(idc); |
| XsbReader saver = new XsbReader(handle); |
| saver.writeIdConstraintData(idc); |
| saver.writeRealHeader(handle, FILETYPE_SCHEMAIDENTITYCONSTRAINT); |
| saver.writeIdConstraintData(idc); |
| saver.writeEnd(); |
| } |
| |
| void saveType(SchemaType type) |
| { |
| String handle = _localHandles.handleForType(type); |
| XsbReader saver = new XsbReader(handle); |
| saver.writeTypeData(type); |
| saver.writeRealHeader(handle, FILETYPE_SCHEMATYPE); |
| saver.writeTypeData(type); |
| saver.writeEnd(); |
| } |
| |
| public static String crackPointer(InputStream stream) |
| { |
| DataInputStream input = null; |
| try |
| { |
| input = new DataInputStream(stream); |
| |
| int magic = input.readInt(); |
| if (magic != DATA_BABE) |
| return null; |
| |
| int majorver = input.readShort(); |
| int minorver = input.readShort(); |
| |
| if (majorver != MAJOR_VERSION) |
| return null; |
| |
| if (minorver > MINOR_VERSION) |
| return null; |
| |
| if (majorver > 2 || majorver == 2 && minorver >= 18) |
| input.readShort(); // release number present in atLeast(2, 18, 0) |
| |
| int actualfiletype = input.readShort(); |
| if (actualfiletype != FILETYPE_SCHEMAPOINTER) |
| return null; |
| |
| StringPool stringPool = new StringPool("pointer", "unk"); |
| stringPool.readFrom(input); |
| |
| return stringPool.stringForCode(input.readShort()); |
| } |
| catch (IOException e) |
| { |
| return null; |
| } |
| finally |
| { |
| if (input != null) |
| try { input.close(); } catch (IOException e) {} |
| } |
| } |
| |
| private class XsbReader |
| { |
| DataInputStream _input; |
| DataOutputStream _output; |
| StringPool _stringPool; |
| String _handle; |
| private int _majorver; |
| private int _minorver; |
| private int _releaseno; |
| int _actualfiletype; |
| |
| public XsbReader(String handle, int filetype) |
| { |
| String resourcename = _basePackage + handle + ".xsb"; |
| InputStream rawinput = getLoaderStream(resourcename); |
| if (rawinput == null) |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Could not locate compiled schema resource " + resourcename, _name, handle, SchemaTypeLoaderException.NO_RESOURCE); |
| |
| _input = new DataInputStream(rawinput); |
| _handle = handle; |
| |
| int magic = readInt(); |
| if (magic != DATA_BABE) |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong magic cookie", _name, handle, SchemaTypeLoaderException.WRONG_MAGIC_COOKIE); |
| |
| _majorver = readShort(); |
| _minorver = readShort(); |
| |
| if (_majorver != MAJOR_VERSION) |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong major version - expecting " + MAJOR_VERSION + ", got " + _majorver, _name, handle, SchemaTypeLoaderException.WRONG_MAJOR_VERSION); |
| |
| if (_minorver > MINOR_VERSION) |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Incompatible minor version - expecting up to " + MINOR_VERSION + ", got " + _minorver, _name, handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION); |
| |
| // Clip to 14 because we're not backward compatible with earlier |
| // minor versions. Remove this when upgrading to a new major |
| // version |
| |
| if (_minorver < 14) |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Incompatible minor version - expecting at least 14, got " + _minorver, _name, handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION); |
| |
| if (atLeast(2, 18, 0)) |
| _releaseno = readShort(); |
| |
| int actualfiletype = readShort(); |
| if (actualfiletype != filetype && filetype != -1) |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: File has the wrong type - expecting type " + filetype + ", got type " + actualfiletype, _name, handle, SchemaTypeLoaderException.WRONG_FILE_TYPE); |
| |
| _stringPool = new StringPool(_handle, _name); |
| _stringPool.readFrom(_input); |
| |
| _actualfiletype = actualfiletype; |
| } |
| |
| protected boolean atLeast(int majorver, int minorver, int releaseno) |
| { |
| if (_majorver > majorver) |
| return true; |
| if (_majorver < majorver) |
| return false; |
| if (_minorver > minorver) |
| return true; |
| if (_minorver < minorver) |
| return false; |
| return (_releaseno >= releaseno); |
| } |
| |
| protected boolean atMost(int majorver, int minorver, int releaseno) |
| { |
| if (_majorver > majorver) |
| return false; |
| if (_majorver < majorver) |
| return true; |
| if (_minorver > minorver) |
| return false; |
| if (_minorver < minorver) |
| return true; |
| return (_releaseno <= releaseno); |
| } |
| |
| int getActualFiletype() |
| { |
| return _actualfiletype; |
| } |
| |
| XsbReader(String handle) |
| { |
| _handle = handle; |
| _stringPool = new StringPool(_handle, _name); |
| } |
| |
| void writeRealHeader(String handle, int filetype) |
| { |
| // hackeroo: if handle contains a "/" it's not relative. |
| String resourcename; |
| |
| if (handle.indexOf('/') >= 0) |
| resourcename = handle + ".xsb"; |
| else |
| resourcename = _basePackage + handle + ".xsb"; |
| |
| OutputStream rawoutput = getSaverStream(resourcename); |
| if (rawoutput == null) |
| throw new SchemaTypeLoaderException("Could not write compiled schema resource " + resourcename, _name, handle, SchemaTypeLoaderException.NOT_WRITEABLE); |
| |
| _output = new DataOutputStream(rawoutput); |
| _handle = handle; |
| |
| writeInt(DATA_BABE); |
| writeShort(MAJOR_VERSION); |
| writeShort(MINOR_VERSION); |
| writeShort(RELEASE_NUMBER); |
| writeShort(filetype); |
| |
| _stringPool.writeTo(_output); |
| } |
| |
| void readEnd() |
| { |
| try |
| { |
| if (_input != null) |
| _input.close(); |
| } |
| catch (IOException e) |
| { |
| // oh, well. |
| } |
| _input = null; |
| _stringPool = null; |
| _handle = null; |
| } |
| |
| void writeEnd() |
| { |
| try |
| { |
| if (_output != null) |
| { |
| _output.flush(); |
| _output.close(); |
| } |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| _output = null; |
| _stringPool = null; |
| _handle = null; |
| } |
| |
| int fileTypeFromComponentType(int componentType) |
| { |
| switch (componentType) |
| { |
| case SchemaComponent.TYPE: |
| return SchemaTypeSystemImpl.FILETYPE_SCHEMATYPE; |
| case SchemaComponent.ELEMENT: |
| return SchemaTypeSystemImpl.FILETYPE_SCHEMAELEMENT; |
| case SchemaComponent.ATTRIBUTE: |
| return SchemaTypeSystemImpl.FILETYPE_SCHEMAATTRIBUTE; |
| case SchemaComponent.MODEL_GROUP: |
| return SchemaTypeSystemImpl.FILETYPE_SCHEMAMODELGROUP; |
| case SchemaComponent.ATTRIBUTE_GROUP: |
| return SchemaTypeSystemImpl.FILETYPE_SCHEMAATTRIBUTEGROUP; |
| case SchemaComponent.IDENTITY_CONSTRAINT: |
| return SchemaTypeSystemImpl.FILETYPE_SCHEMAIDENTITYCONSTRAINT; |
| default: |
| throw new IllegalStateException("Unexpected component type"); |
| } |
| } |
| |
| void writeIndexData() |
| { |
| // has a handle pool (count, handle/type, handle/type...) |
| writeHandlePool(_localHandles); |
| |
| // then a qname map of global elements (count, qname/handle, qname/handle...) |
| writeQNameMap(globalElements()); |
| |
| // qname map of global attributes |
| writeQNameMap(globalAttributes()); |
| |
| // qname map of model groups |
| writeQNameMap(modelGroups()); |
| |
| // qname map of attribute groups |
| writeQNameMap(attributeGroups()); |
| |
| // qname map of identity constraints |
| writeQNameMap(identityConstraints()); |
| |
| // qname map of global types |
| writeQNameMap(globalTypes()); |
| |
| // qname map of document types, by the qname of the contained element |
| writeDocumentTypeMap(documentTypes()); |
| |
| // qname map of attribute types, by the qname of the contained attribute |
| writeAttributeTypeMap(attributeTypes()); |
| |
| // all the types by classname |
| writeClassnameMap(_typeRefsByClassname); |
| |
| // all the namespaces |
| writeNamespaces(_namespaces); |
| |
| // VERSION 2.15 and newer below |
| writeQNameMap(redefinedGlobalTypes()); |
| writeQNameMap(redefinedModelGroups()); |
| writeQNameMap(redefinedAttributeGroups()); |
| } |
| |
| void writeHandlePool(HandlePool pool) |
| { |
| writeShort(pool._componentsToHandles.size()); |
| for (Iterator i = pool._componentsToHandles.keySet().iterator(); i.hasNext(); ) |
| { |
| SchemaComponent comp = (SchemaComponent)i.next(); |
| String handle = (String)pool._componentsToHandles.get(comp); |
| int code = fileTypeFromComponentType(comp.getComponentType()); |
| writeString(handle); |
| writeShort(code); |
| } |
| } |
| |
| void readHandlePool(HandlePool pool) |
| { |
| if (pool._handlesToRefs.size() != 0 || pool._started) |
| throw new IllegalStateException("Nonempty handle set before read"); |
| |
| int size = readShort(); |
| for (int i = 0; i < size; i++) |
| { |
| String handle = readString(); |
| short code = readShort(); |
| Object result; |
| switch (code) |
| { |
| case FILETYPE_SCHEMATYPE: |
| result = new SchemaType.Ref(getTypeSystem(), handle); |
| break; |
| case FILETYPE_SCHEMAELEMENT: |
| result = new SchemaGlobalElement.Ref(getTypeSystem(), handle); |
| break; |
| case FILETYPE_SCHEMAATTRIBUTE: |
| result = new SchemaGlobalAttribute.Ref(getTypeSystem(), handle); |
| break; |
| case FILETYPE_SCHEMAMODELGROUP: |
| result = new SchemaModelGroup.Ref(getTypeSystem(), handle); |
| break; |
| case FILETYPE_SCHEMAATTRIBUTEGROUP: |
| result = new SchemaAttributeGroup.Ref(getTypeSystem(), handle); |
| break; |
| case FILETYPE_SCHEMAIDENTITYCONSTRAINT: |
| result = new SchemaIdentityConstraint.Ref(getTypeSystem(), handle); |
| break; |
| default: |
| throw new SchemaTypeLoaderException("Schema index has an unrecognized entry of type " + code, _name, handle, SchemaTypeLoaderException.UNRECOGNIZED_INDEX_ENTRY); |
| } |
| pool._handlesToRefs.put(handle, result); |
| } |
| } |
| |
| short readShort() |
| { |
| try |
| { |
| return _input.readShort(); |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| |
| void writeShort(int s) |
| { |
| if (s > Short.MAX_VALUE || s < Short.MIN_VALUE) |
| throw new SchemaTypeLoaderException("Value " + s + " out of range: must fit in a 16-bit short.", _name, _handle, SchemaTypeLoaderException.INT_TOO_LARGE); |
| if (_output != null) |
| { |
| try |
| { |
| _output.writeShort(s); |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| } |
| |
| int readInt() |
| { |
| try |
| { |
| return _input.readInt(); |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| |
| void writeInt(int i) |
| { |
| if (_output != null) |
| { |
| try |
| { |
| _output.writeInt(i); |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| } |
| |
| String readString() |
| { |
| return _stringPool.stringForCode(readShort()); |
| } |
| |
| void writeString(String str) |
| { |
| int code = _stringPool.codeForString(str); |
| writeShort(code); |
| } |
| |
| QName readQName() |
| { |
| String namespace = readString(); |
| String localname = readString(); |
| if (localname == null) |
| return null; |
| return new QName(namespace, localname); |
| } |
| |
| void writeQName(QName qname) |
| { |
| if (qname == null) |
| { |
| writeString(null); |
| writeString(null); |
| return; |
| } |
| writeString(qname.getNamespaceURI()); |
| writeString(qname.getLocalPart()); |
| } |
| |
| SOAPArrayType readSOAPArrayType() |
| { |
| QName qName = readQName(); |
| String dimensions = readString(); |
| if (qName == null) |
| return null; |
| return new SOAPArrayType(qName, dimensions); |
| } |
| |
| void writeSOAPArrayType(SOAPArrayType arrayType) |
| { |
| if (arrayType == null) |
| { |
| writeQName(null); |
| writeString(null); |
| } |
| else |
| { |
| writeQName(arrayType.getQName()); |
| writeString(arrayType.soap11DimensionString()); |
| } |
| } |
| |
| SchemaComponent.Ref readHandle() |
| { |
| String handle = readString(); |
| if (handle == null) |
| return null; |
| |
| if (handle.charAt(0) != '_') |
| return _localHandles.refForHandle(handle); |
| |
| switch (handle.charAt(2)) |
| { |
| case 'I': // _BI_ - built-in schema type system |
| return ((SchemaType)BuiltinSchemaTypeSystem.get().resolveHandle(handle)).getRef(); |
| case 'T': // _XT_ - external type |
| return _linker.findTypeRef(QNameHelper.forPretty(handle, 4)); |
| case 'E': // _XE_ - external element |
| return _linker.findElementRef(QNameHelper.forPretty(handle, 4)); |
| case 'A': // _XA_ - external attribute |
| return _linker.findAttributeRef(QNameHelper.forPretty(handle, 4)); |
| case 'M': // _XM_ - external model group |
| return _linker.findModelGroupRef(QNameHelper.forPretty(handle, 4)); |
| case 'N': // _XN_ - external attribute group |
| return _linker.findAttributeGroupRef(QNameHelper.forPretty(handle, 4)); |
| case 'D': // _XD_ - external identity constraint |
| return _linker.findIdentityConstraintRef(QNameHelper.forPretty(handle, 4)); |
| case 'R': // _XR_ - external ref to attribute's type |
| return _linker.findAttribute(QNameHelper.forPretty(handle, 4)).getType().getRef(); |
| case 'S': // _XS_ - external ref to element's type |
| return _linker.findElement(QNameHelper.forPretty(handle, 4)).getType().getRef(); |
| default: |
| throw new SchemaTypeLoaderException("Cannot resolve handle " + handle, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE); |
| } |
| } |
| |
| void writeHandle(SchemaComponent comp) |
| { |
| if (comp == null || comp.getTypeSystem() == getTypeSystem()) |
| { |
| writeString(_localHandles.handleForComponent(comp)); |
| return; |
| } |
| |
| switch (comp.getComponentType()) |
| { |
| case SchemaComponent.ATTRIBUTE: |
| writeString("_XA_" + QNameHelper.pretty(comp.getName())); |
| return; |
| case SchemaComponent.MODEL_GROUP: |
| writeString("_XM_" + QNameHelper.pretty(comp.getName())); |
| return; |
| case SchemaComponent.ATTRIBUTE_GROUP: |
| writeString("_XN_" + QNameHelper.pretty(comp.getName())); |
| return; |
| case SchemaComponent.ELEMENT: |
| writeString("_XE_" + QNameHelper.pretty(comp.getName())); |
| return; |
| case SchemaComponent.IDENTITY_CONSTRAINT: |
| writeString("_XD_" + QNameHelper.pretty(comp.getName())); |
| return; |
| case SchemaComponent.TYPE: |
| SchemaType type = (SchemaType)comp; |
| if (type.isBuiltinType()) |
| { |
| writeString("_BI_" + type.getName().getLocalPart()); |
| return; |
| } |
| |
| // fix for CR120759 - added output of types _XR_ & _XS_ |
| // when an attribute (_XR_) or element (_XS_) declaration |
| // uses ref to refer to an attribute or element in another |
| // schema and the type of that attribute or element |
| // is an anonymous (local) type |
| if (type.getName() != null) |
| { |
| writeString("_XT_" + QNameHelper.pretty(type.getName())); |
| } |
| else |
| { |
| SchemaField sf = type.getContainerField(); |
| assert (sf != null); |
| if (sf.isAttribute()) |
| { |
| writeString("_XR_" + QNameHelper.pretty(sf.getName())); |
| } |
| else |
| { |
| writeString("_XS_" + QNameHelper.pretty(sf.getName())); |
| } |
| } |
| |
| return; |
| |
| default: |
| assert(false); |
| throw new SchemaTypeLoaderException("Cannot write handle for component " + comp, _name, _handle, SchemaTypeLoaderException.BAD_HANDLE); |
| } |
| } |
| |
| SchemaType.Ref readTypeRef() |
| { |
| return (SchemaType.Ref)readHandle(); |
| } |
| |
| void writeType(SchemaType type) |
| { |
| writeHandle(type); |
| } |
| |
| Map readQNameRefMap() |
| { |
| Map result = new HashMap(); |
| int size = readShort(); |
| for (int i = 0; i < size; i++) |
| { |
| QName name = readQName(); |
| SchemaComponent.Ref obj = readHandle(); |
| result.put(name, obj); |
| } |
| return result; |
| } |
| |
| void writeQNameMap(SchemaComponent[] components) |
| { |
| writeShort(components.length); |
| for (int i = 0; i < components.length; i++) |
| { |
| writeQName(components[i].getName()); |
| writeHandle(components[i]); |
| } |
| } |
| |
| void writeDocumentTypeMap(SchemaType[] doctypes) |
| { |
| writeShort(doctypes.length); |
| for (int i = 0; i < doctypes.length; i++) |
| { |
| writeQName(doctypes[i].getDocumentElementName()); |
| writeHandle(doctypes[i]); |
| } |
| } |
| |
| void writeAttributeTypeMap(SchemaType[] attrtypes) |
| { |
| writeShort(attrtypes.length); |
| for (int i = 0; i < attrtypes.length; i++) |
| { |
| writeQName(attrtypes[i].getAttributeTypeAttributeName()); |
| writeHandle(attrtypes[i]); |
| } |
| } |
| |
| SchemaType.Ref[] readTypeRefArray() |
| { |
| int size = readShort(); |
| SchemaType.Ref[] result = new SchemaType.Ref[size]; |
| for (int i = 0; i < size; i++) |
| { |
| result[i] = readTypeRef(); |
| } |
| return result; |
| } |
| |
| void writeTypeArray(SchemaType[] array) |
| { |
| writeShort(array.length); |
| for (int i = 0; i < array.length; i++) |
| { |
| writeHandle(array[i]); |
| } |
| } |
| |
| Map readClassnameRefMap() |
| { |
| Map result = new HashMap(); |
| int size = readShort(); |
| for (int i = 0; i < size; i++) |
| { |
| String name = readString(); |
| SchemaComponent.Ref obj = readHandle(); |
| result.put(name, obj); |
| } |
| return result; |
| } |
| |
| void writeClassnameMap(Map typesByClass) |
| { |
| writeShort(typesByClass.size()); |
| for (Iterator i = typesByClass.keySet().iterator(); i.hasNext(); ) |
| { |
| String className = (String)i.next(); |
| writeString(className); |
| writeHandle(((SchemaType.Ref)typesByClass.get(className)).get()); |
| } |
| } |
| |
| Set readNamespaces() |
| { |
| Set result = new HashSet(); |
| int size = readShort(); |
| for (int i = 0; i < size; i++) |
| { |
| String ns = readString(); |
| result.add(ns); |
| } |
| return result; |
| } |
| |
| void writeNamespaces(Set namespaces) |
| { |
| writeShort(namespaces.size()); |
| for (Iterator i = namespaces.iterator(); i.hasNext(); ) |
| { |
| String ns = (String)i.next(); |
| writeString(ns); |
| } |
| } |
| |
| OutputStream getSaverStream(String name) |
| { |
| File targetFile = new File(_baseSaveDir, name); |
| try |
| { |
| targetFile.getParentFile().mkdirs(); |
| return new FileOutputStream(targetFile); |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| |
| InputStream getLoaderStream(String resourcename) |
| { |
| return _resourceLoader.getResourceAsStream(resourcename); |
| } |
| |
| /** |
| * Finishes loading an element after the header has already been loaded. |
| */ |
| public SchemaGlobalElement finishLoadingElement() |
| { |
| String handle = null; |
| try |
| { |
| SchemaGlobalElementImpl impl = new SchemaGlobalElementImpl(getTypeSystem()); |
| short particleType = readShort(); |
| if (particleType != SchemaParticle.ELEMENT) |
| throw new SchemaTypeLoaderException("Wrong particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE); |
| loadParticle(impl, SchemaParticle.ELEMENT, true); |
| impl.setFilename(readString()); |
| return impl; |
| } |
| catch (SchemaTypeLoaderException e) |
| { |
| throw e; |
| } |
| catch (Exception e) |
| { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } |
| finally |
| { |
| readEnd(); |
| } |
| } |
| |
| public SchemaGlobalAttribute finishLoadingAttribute() |
| { |
| SchemaGlobalAttributeImpl impl = new SchemaGlobalAttributeImpl(getTypeSystem()); |
| try |
| { |
| loadAttribute(impl); |
| impl.setFilename(readString()); |
| |
| return impl; |
| } |
| catch (SchemaTypeLoaderException e) |
| { |
| throw e; |
| } |
| catch (Exception e) |
| { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } |
| finally |
| { |
| readEnd(); |
| } |
| } |
| |
| SchemaModelGroup finishLoadingModelGroup() |
| { |
| SchemaModelGroupImpl impl = new SchemaModelGroupImpl(getTypeSystem()); |
| |
| try |
| { |
| loadModelGroup(impl); |
| return impl; |
| } |
| catch (SchemaTypeLoaderException e) |
| { |
| throw e; |
| } |
| catch (Exception e) |
| { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } |
| finally |
| { |
| readEnd(); |
| } |
| } |
| |
| SchemaIdentityConstraint finishLoadingIdentityConstraint() |
| { |
| try { |
| SchemaIdentityConstraintImpl impl = new SchemaIdentityConstraintImpl(getTypeSystem()); |
| impl.setName(readQName()); |
| impl.setConstraintCategory(readShort()); |
| impl.setSelector(readString()); |
| |
| String[] fields = new String[readShort()]; |
| for (int i = 0 ; i < fields.length ; i++) |
| fields[i] = readString(); |
| impl.setFields(fields); |
| |
| if (impl.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) |
| impl.setReferencedKey((SchemaIdentityConstraint.Ref)readHandle()); |
| |
| int mapCount = readShort(); |
| Map nsMappings = new HashMap(); |
| for (int i = 0 ; i < mapCount ; i++) |
| { |
| String prefix = readString(); |
| String uri = readString(); |
| nsMappings.put(prefix, uri); |
| } |
| impl.setNSMap(nsMappings); |
| |
| return impl; |
| } |
| catch (SchemaTypeLoaderException e) |
| { |
| throw e; |
| } |
| catch (Exception e) |
| { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } |
| finally |
| { |
| readEnd(); |
| } |
| } |
| |
| SchemaAttributeGroup finishLoadingAttributeGroup() |
| { |
| SchemaAttributeGroupImpl impl = new SchemaAttributeGroupImpl(getTypeSystem()); |
| |
| try |
| { |
| loadAttributeGroup(impl); |
| return impl; |
| } |
| catch (SchemaTypeLoaderException e) |
| { |
| throw e; |
| } |
| catch (Exception e) |
| { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } |
| finally |
| { |
| readEnd(); |
| } |
| } |
| |
| public SchemaType finishLoadingType() |
| { |
| try |
| { |
| SchemaTypeImpl impl = new SchemaTypeImpl(getTypeSystem(), true); |
| impl.setName(readQName()); |
| impl.setOuterSchemaTypeRef(readTypeRef()); |
| impl.setBaseDepth(readShort()); |
| impl.setBaseTypeRef(readTypeRef()); |
| impl.setDerivationType(readShort()); |
| |
| switch (readShort()) |
| { |
| case FIELD_GLOBAL: |
| impl.setContainerFieldRef(readHandle()); |
| break; |
| case FIELD_LOCALATTR: |
| impl.setContainerFieldIndex((short)1, readShort()); |
| break; |
| case FIELD_LOCALELT: |
| impl.setContainerFieldIndex((short)2, readShort()); |
| break; |
| } |
| impl.setFullJavaName(readString()); |
| impl.setFullJavaImplName(readString()); |
| |
| impl.setAnonymousTypeRefs(readTypeRefArray()); |
| |
| impl.setAnonymousUnionMemberOrdinal(readShort()); |
| |
| int flags; |
| flags = readInt(); |
| |
| |
| boolean isComplexType = ((flags & FLAG_SIMPLE_TYPE) == 0); |
| impl.setCompiled((flags & FLAG_COMPILED) != 0); |
| impl.setDocumentType((flags & FLAG_DOCUMENT_TYPE) != 0); |
| impl.setAttributeType((flags & FLAG_ATTRIBUTE_TYPE) != 0); |
| impl.setSimpleType(!isComplexType); |
| |
| short complexVariety = SchemaType.NOT_COMPLEX_TYPE; |
| if (isComplexType) |
| { |
| impl.setAbstractFinal((flags & FLAG_ABSTRACT) != 0, |
| (flags & FLAG_FINAL_EXT) != 0, |
| (flags & FLAG_FINAL_REST) != 0, |
| (flags & FLAG_FINAL_LIST) != 0, |
| (flags & FLAG_FINAL_UNION) != 0); |
| impl.setBlock((flags & FLAG_BLOCK_EXT) != 0, |
| (flags & FLAG_BLOCK_REST) != 0); |
| |
| impl.setOrderSensitive((flags & FLAG_ORDER_SENSITIVE) != 0); |
| complexVariety = readShort(); |
| impl.setComplexTypeVariety(complexVariety); |
| |
| // Attribute Model Table |
| SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl(); |
| |
| short attrCount = readShort(); |
| for (int i = 0; i < attrCount; i++) |
| attrModel.addAttribute(readAttributeData()); |
| |
| attrModel.setWildcardSet(readQNameSet()); |
| attrModel.setWildcardProcess(readShort()); |
| |
| // Attribute Property Table |
| Map attrProperties = new LinkedHashMap(); |
| short attrPropCount = readShort(); |
| for (int i = 0; i < attrPropCount; i++) |
| { |
| SchemaProperty prop = readPropertyData(); |
| if (!prop.isAttribute()) |
| throw new SchemaTypeLoaderException("Attribute property " + i + " is not an attribute", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE); |
| attrProperties.put(prop.getName(), prop); |
| } |
| |
| SchemaParticle contentModel = null; |
| Map elemProperties = null; |
| short isAll = 0; |
| |
| if (complexVariety == SchemaType.ELEMENT_CONTENT || complexVariety == SchemaType.MIXED_CONTENT) |
| { |
| // Content Model Tree |
| isAll = readShort(); |
| SchemaParticle[] parts = readParticleArray(); |
| if (parts.length == 1) |
| contentModel = parts[0]; |
| else if (parts.length == 0) |
| contentModel = null; |
| else |
| throw new SchemaTypeLoaderException("Content model not well-formed", _name, _handle, SchemaTypeLoaderException.MALFORMED_CONTENT_MODEL); |
| |
| // Element Property Table |
| |
| elemProperties = new LinkedHashMap(); |
| short elemPropCount = readShort(); |
| for (int i = 0; i < elemPropCount; i++) |
| { |
| SchemaProperty prop = readPropertyData(); |
| if (prop.isAttribute()) |
| throw new SchemaTypeLoaderException("Element property " + i + " is not an element", _name, _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE); |
| elemProperties.put(prop.getName(), prop); |
| } |
| } |
| |
| impl.setContentModel(contentModel, attrModel, elemProperties, attrProperties, isAll == 1); |
| StscComplexTypeResolver.WildcardResult wcElt = StscComplexTypeResolver.summarizeEltWildcards(contentModel); |
| StscComplexTypeResolver.WildcardResult wcAttr = StscComplexTypeResolver.summarizeAttrWildcards(attrModel); |
| impl.setWildcardSummary(wcElt.typedWildcards, wcElt.hasWildcards, wcAttr.typedWildcards, wcAttr.hasWildcards); |
| } |
| |
| if (!isComplexType || complexVariety == SchemaType.SIMPLE_CONTENT) |
| { |
| short simpleVariety = readShort(); |
| impl.setSimpleTypeVariety(simpleVariety); |
| |
| boolean isStringEnum = ((flags & FLAG_STRINGENUM) != 0); |
| |
| impl.setOrdered((flags & FLAG_ORDERED) != 0 ? SchemaType.UNORDERED : ((flags & FLAG_TOTAL_ORDER) != 0 ? SchemaType.TOTAL_ORDER : SchemaType.PARTIAL_ORDER)); |
| impl.setBounded((flags & FLAG_BOUNDED) != 0); |
| impl.setFinite((flags & FLAG_FINITE) != 0); |
| impl.setNumeric((flags & FLAG_NUMERIC) != 0); |
| impl.setUnionOfLists((flags & FLAG_UNION_OF_LISTS) != 0); |
| impl.setSimpleFinal((flags & FLAG_FINAL_REST) != 0, |
| (flags & FLAG_FINAL_LIST) != 0, |
| (flags & FLAG_FINAL_UNION) != 0); |
| |
| XmlValueRef[] facets = new XmlValueRef[SchemaType.LAST_FACET + 1]; |
| boolean[] fixedFacets = new boolean[SchemaType.LAST_FACET + 1]; |
| short facetCount = readShort(); |
| for (int i = 0; i < facetCount; i++) |
| { |
| short facetCode = readShort(); |
| facets[facetCode] = readXmlValueObject(); |
| fixedFacets[facetCode] = (readShort() == 1); |
| } |
| impl.setBasicFacets(facets, fixedFacets); |
| |
| impl.setWhiteSpaceRule(readShort()); |
| |
| impl.setPatternFacet((flags & FLAG_HAS_PATTERN) != 0); |
| |
| short patternCount = readShort(); |
| org.apache.xmlbeans.impl.regex.RegularExpression[] patterns = new org.apache.xmlbeans.impl.regex.RegularExpression[patternCount]; |
| for (int i = 0; i < patternCount; i++) |
| { |
| patterns[i] = new org.apache.xmlbeans.impl.regex.RegularExpression(readString(), "X"); |
| } |
| impl.setPatterns(patterns); |
| |
| short enumCount = readShort(); |
| XmlValueRef[] enumValues = new XmlValueRef[enumCount]; |
| for (int i = 0; i < enumCount; i++) |
| { |
| enumValues[i] = readXmlValueObject(); |
| } |
| impl.setEnumerationValues(enumCount == 0 ? null : enumValues); |
| |
| impl.setBaseEnumTypeRef(readTypeRef()); |
| if (isStringEnum) |
| { |
| short seCount = readShort(); |
| SchemaStringEnumEntry[] entries = new SchemaStringEnumEntry[seCount]; |
| for (int i = 0; i < seCount; i++) |
| { |
| entries[i] = new SchemaStringEnumEntryImpl(readString(), readShort(), readString()); |
| } |
| impl.setStringEnumEntries(entries); |
| } |
| |
| switch (simpleVariety) |
| { |
| case SchemaType.ATOMIC: |
| impl.setPrimitiveTypeRef(readTypeRef()); |
| impl.setDecimalSize(readInt()); |
| break; |
| |
| case SchemaType.LIST: |
| impl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef()); |
| impl.setListItemTypeRef(readTypeRef()); |
| break; |
| |
| case SchemaType.UNION: |
| impl.setPrimitiveTypeRef(BuiltinSchemaTypeSystem.ST_ANY_SIMPLE.getRef()); |
| impl.setUnionMemberTypeRefs(readTypeRefArray()); |
| break; |
| |
| default: |
| throw new SchemaTypeLoaderException("Simple type does not have a recognized variety", _name, _handle, SchemaTypeLoaderException.WRONG_SIMPLE_VARIETY); |
| } |
| } |
| |
| impl.setFilename(readString()); |
| |
| return impl; |
| } |
| catch (SchemaTypeLoaderException e) |
| { |
| throw e; |
| } |
| catch (Exception e) |
| { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", _name, _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } |
| finally |
| { |
| readEnd(); |
| } |
| } |
| |
| void writeTypeData(SchemaType type) |
| { |
| writeQName(type.getName()); |
| writeType(type.getOuterType()); |
| writeShort(((SchemaTypeImpl)type).getBaseDepth()); |
| writeType(type.getBaseType()); |
| writeShort(type.getDerivationType()); |
| if (type.getContainerField() == null) |
| { |
| writeShort(FIELD_NONE); |
| } |
| else if (type.getOuterType().isAttributeType() || type.getOuterType().isDocumentType()) |
| { |
| writeShort(FIELD_GLOBAL); |
| writeHandle((SchemaComponent)type.getContainerField()); |
| } |
| else if (type.getContainerField().isAttribute()) |
| { |
| writeShort(FIELD_LOCALATTR); |
| writeShort(((SchemaTypeImpl)type.getOuterType()).getIndexForLocalAttribute((SchemaLocalAttribute)type.getContainerField())); |
| } |
| else |
| { |
| writeShort(FIELD_LOCALELT); |
| writeShort(((SchemaTypeImpl)type.getOuterType()).getIndexForLocalElement((SchemaLocalElement)type.getContainerField())); |
| } |
| writeString(type.getFullJavaName()); |
| writeString(type.getFullJavaImplName()); |
| writeTypeArray(type.getAnonymousTypes()); |
| writeShort(type.getAnonymousUnionMemberOrdinal()); |
| |
| int flags = 0; |
| if (type.isSimpleType()) |
| flags |= FLAG_SIMPLE_TYPE; |
| if (type.isDocumentType()) |
| flags |= FLAG_DOCUMENT_TYPE; |
| if (type.isAttributeType()) |
| flags |= FLAG_ATTRIBUTE_TYPE; |
| if (type.ordered() != SchemaType.UNORDERED) |
| flags |= FLAG_ORDERED; |
| if (type.ordered() == SchemaType.TOTAL_ORDER) |
| flags |= FLAG_TOTAL_ORDER; |
| if (type.isBounded()) |
| flags |= FLAG_BOUNDED; |
| if (type.isFinite()) |
| flags |= FLAG_FINITE; |
| if (type.isNumeric()) |
| flags |= FLAG_NUMERIC; |
| if (type.hasStringEnumValues()) |
| flags |= FLAG_STRINGENUM; |
| if (((SchemaTypeImpl)type).isUnionOfLists()) |
| flags |= FLAG_UNION_OF_LISTS; |
| if (type.hasPatternFacet()) |
| flags |= FLAG_HAS_PATTERN; |
| if (type.isOrderSensitive()) |
| flags |= FLAG_ORDER_SENSITIVE; |
| |
| if (type.blockExtension()) |
| flags |= FLAG_BLOCK_EXT; |
| if (type.blockRestriction()) |
| flags |= FLAG_BLOCK_REST; |
| if (type.finalExtension()) |
| flags |= FLAG_FINAL_EXT; |
| if (type.finalRestriction()) |
| flags |= FLAG_FINAL_EXT; |
| if (type.finalList()) |
| flags |= FLAG_FINAL_LIST; |
| if (type.finalUnion()) |
| flags |= FLAG_FINAL_UNION; |
| if (type.isAbstract()) |
| flags |= FLAG_ABSTRACT; |
| |
| writeInt(flags); |
| |
| if (!type.isSimpleType()) |
| { |
| writeShort(type.getContentType()); |
| |
| // Attribute Model Table |
| SchemaAttributeModel attrModel = type.getAttributeModel(); |
| SchemaLocalAttribute[] attrs = attrModel.getAttributes(); |
| |
| writeShort(attrs.length); |
| for (int i = 0; i < attrs.length; i++) |
| writeAttributeData(attrs[i]); |
| |
| writeQNameSet(attrModel.getWildcardSet()); |
| writeShort(attrModel.getWildcardProcess()); |
| |
| // Attribute Property Table |
| SchemaProperty[] attrProperties = type.getAttributeProperties(); |
| writeShort(attrProperties.length); |
| for (int i = 0; i < attrProperties.length; i++) |
| writePropertyData(attrProperties[i]); |
| |
| if (type.getContentType() == SchemaType.ELEMENT_CONTENT || |
| type.getContentType() == SchemaType.MIXED_CONTENT) |
| { |
| // Content Model Tree |
| writeShort(type.hasAllContent() ? 1 : 0); |
| SchemaParticle[] parts; |
| if (type.getContentModel() != null) |
| parts = new SchemaParticle[] { type.getContentModel() }; |
| else |
| parts = new SchemaParticle[0]; |
| |
| writeParticleArray(parts); |
| |
| // Element Property Table |
| SchemaProperty[] eltProperties = type.getElementProperties(); |
| writeShort(eltProperties.length); |
| for (int i = 0; i < eltProperties.length; i++) |
| writePropertyData(eltProperties[i]); |
| } |
| } |
| |
| if (type.isSimpleType() || type.getContentType() == SchemaType.SIMPLE_CONTENT) |
| { |
| writeShort(type.getSimpleVariety()); |
| |
| int facetCount = 0; |
| for (int i = 0; i <= SchemaType.LAST_FACET; i++) |
| if (type.getFacet(i) != null) |
| facetCount++; |
| writeShort(facetCount); |
| for (int i = 0; i <= SchemaType.LAST_FACET; i++) |
| { |
| XmlAnySimpleType facet = type.getFacet(i); |
| if (facet != null) |
| { |
| writeShort(i); |
| writeXmlValueObject(facet); |
| writeShort(type.isFacetFixed(i) ? 1 : 0); |
| } |
| } |
| |
| writeShort(type.getWhiteSpaceRule()); |
| |
| org.apache.xmlbeans.impl.regex.RegularExpression[] patterns = ((SchemaTypeImpl)type).getPatternExpressions(); |
| writeShort(patterns.length); |
| for (int i = 0; i < patterns.length; i++) |
| writeString(patterns[i].getPattern()); |
| |
| XmlAnySimpleType[] enumValues = type.getEnumerationValues(); |
| if (enumValues == null) |
| writeShort(0); |
| else |
| { |
| writeShort(enumValues.length); |
| for (int i = 0; i < enumValues.length; i++) |
| writeXmlValueObject(enumValues[i]); |
| } |
| |
| // new for version 2.3 |
| writeType(type.getBaseEnumType()); |
| if (type.hasStringEnumValues()) |
| { |
| SchemaStringEnumEntry[] entries = type.getStringEnumEntries(); |
| writeShort(entries.length); |
| for (int i = 0; i < entries.length; i++) |
| { |
| writeString(entries[i].getString()); |
| writeShort(entries[i].getIntValue()); |
| writeString(entries[i].getEnumName()); |
| } |
| } |
| |
| switch (type.getSimpleVariety()) |
| { |
| case SchemaType.ATOMIC: |
| writeType(type.getPrimitiveType()); |
| writeInt(type.getDecimalSize()); |
| break; |
| |
| case SchemaType.LIST: |
| writeType(type.getListItemType()); |
| break; |
| |
| case SchemaType.UNION: |
| writeTypeArray(type.getUnionMemberTypes()); |
| break; |
| } |
| } |
| |
| writeString(type.getSourceName()); |
| } |
| |
| void readExtensionsList() |
| { |
| int count = readShort(); |
| assert count == 0; |
| |
| for (int i = 0; i < count; i++) |
| { |
| readString(); |
| readString(); |
| readString(); |
| } |
| } |
| |
| SchemaLocalAttribute readAttributeData() |
| { |
| SchemaLocalAttributeImpl result = new SchemaLocalAttributeImpl(); |
| loadAttribute(result); |
| return result; |
| } |
| |
| void loadModelGroup(SchemaModelGroupImpl result) |
| { |
| try |
| { |
| result.init(readQName(), readString(), readShort() == 1, atLeast(2, 15, 0) ? readShort() == 1 : false, GroupDocument.Factory.parse( readString() ).getGroup()); |
| } |
| catch ( XmlException e ) |
| { |
| throw new RuntimeException( e.getMessage(), e ); |
| } |
| } |
| |
| void loadAttributeGroup(SchemaAttributeGroupImpl result) |
| { |
| try |
| { |
| result.init( readQName(), readString(), readShort() == 1, atLeast(2, 15, 0) ? readShort() == 1 : false, AttributeGroupDocument.Factory.parse( readString() ).getAttributeGroup()); |
| } |
| catch ( XmlException e ) |
| { |
| throw new RuntimeException( e.getMessage(), e ); |
| } |
| } |
| |
| void loadAttribute(SchemaLocalAttributeImpl result) |
| { |
| // name, type, use, deftext, defval, fixed, soaparraytype |
| result.init(readQName(), readTypeRef(), readShort(), readString(), null, atLeast(2, 16, 0) ? readXmlValueObject() : null, readShort() == 1, readSOAPArrayType()); |
| } |
| |
| void writeAttributeData(SchemaLocalAttribute attr) |
| { |
| writeQName(attr.getName()); |
| writeType(attr.getType()); |
| writeShort(attr.getUse()); |
| writeString(attr.getDefaultText()); |
| writeXmlValueObject(attr.getDefaultValue()); |
| writeShort(attr.isFixed() ? 1 : 0); |
| writeSOAPArrayType(((SchemaWSDLArrayType)attr).getWSDLArrayType()); |
| } |
| |
| void writeIdConstraintData(SchemaIdentityConstraint idc) |
| { |
| writeQName(idc.getName()); |
| writeShort(idc.getConstraintCategory()); |
| writeString(idc.getSelector()); |
| |
| String[] fields = idc.getFields(); |
| writeShort(fields.length); |
| for (int i = 0 ; i < fields.length ; i++) |
| writeString(fields[i]); |
| |
| |
| if (idc.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) |
| writeHandle(idc.getReferencedKey()); |
| |
| Set mappings = idc.getNSMap().entrySet(); |
| writeShort(mappings.size()); |
| for (Iterator it = mappings.iterator() ; it.hasNext() ; ) { |
| Map.Entry e = (Map.Entry)it.next(); |
| String prefix = (String)e.getKey(); |
| String uri = (String)e.getValue(); |
| |
| writeString(prefix); |
| writeString(uri); |
| } |
| |
| } |
| |
| SchemaParticle[] readParticleArray() |
| { |
| SchemaParticle[] result = new SchemaParticle[readShort()]; |
| for (int i = 0; i < result.length; i++) |
| result[i] = readParticleData(); |
| return result; |
| } |
| |
| void writeParticleArray(SchemaParticle[] spa) |
| { |
| writeShort(spa.length); |
| for (int i = 0; i < spa.length; i++) |
| writeParticleData(spa[i]); |
| } |
| |
| SchemaParticle readParticleData() |
| { |
| short particleType = readShort(); |
| SchemaParticleImpl result; |
| if (particleType != SchemaParticle.ELEMENT) |
| result = new SchemaParticleImpl(); |
| else |
| result = new SchemaLocalElementImpl(); |
| loadParticle(result, particleType, false); |
| return result; |
| } |
| |
| void loadParticle(SchemaParticleImpl result, int particleType, boolean global) |
| { |
| short particleFlags = readShort(); |
| |
| result.setParticleType(particleType); |
| result.setMinOccurs(readBigInteger()); |
| result.setMaxOccurs(readBigInteger()); |
| |
| result.setTransitionRules(readQNameSet(), |
| (particleFlags & FLAG_PART_SKIPPABLE) != 0); |
| |
| switch (particleType) |
| { |
| case SchemaParticle.WILDCARD: |
| result.setWildcardSet(readQNameSet()); |
| result.setWildcardProcess(readShort()); |
| break; |
| |
| case SchemaParticle.ELEMENT: |
| SchemaLocalElementImpl lresult = (SchemaLocalElementImpl)result; |
| lresult.setNameAndTypeRef(readQName(), readTypeRef()); |
| lresult.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null); |
| if (atLeast(2, 16, 0)) |
| lresult.setDefaultValue(readXmlValueObject()); |
| lresult.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0); |
| lresult.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0, |
| (particleFlags & FLAG_PART_BLOCKREST) != 0, |
| (particleFlags & FLAG_PART_BLOCKSUBST) != 0); |
| lresult.setWsdlArrayType(readSOAPArrayType()); |
| lresult.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0); |
| if (global) |
| { |
| SchemaGlobalElementImpl gresult = (SchemaGlobalElementImpl)lresult; |
| gresult.setFinal( |
| (particleFlags & FLAG_PART_FINALEXT) != 0, |
| (particleFlags & FLAG_PART_FINALREST) != 0); |
| |
| if (atLeast(2, 17, 0)) |
| gresult.setSubstitutionGroup((SchemaGlobalElement.Ref)readHandle()); |
| |
| short substGroupCount = readShort(); |
| for (int i = 0; i < substGroupCount; i++) |
| { |
| gresult.addSubstitutionGroupMember(readQName()); |
| } |
| } |
| |
| SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()]; |
| |
| for (int i = 0 ; i < idcs.length ; i++) |
| idcs[i] = (SchemaIdentityConstraint.Ref)readHandle(); |
| |
| lresult.setIdentityConstraints(idcs); |
| |
| break; |
| |
| case SchemaParticle.ALL: |
| case SchemaParticle.SEQUENCE: |
| case SchemaParticle.CHOICE: |
| result.setParticleChildren(readParticleArray()); |
| break; |
| |
| default: |
| throw new SchemaTypeLoaderException("Unrecognized particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE); |
| } |
| } |
| |
| void writeParticleData(SchemaParticle part) |
| { |
| writeShort(part.getParticleType()); |
| short flags = 0; |
| if (part.isSkippable()) |
| flags |= FLAG_PART_SKIPPABLE; |
| if (part.getParticleType() == SchemaParticle.ELEMENT) |
| { |
| SchemaLocalElement lpart = (SchemaLocalElement)part; |
| if (lpart.isFixed()) |
| flags |= FLAG_PART_FIXED; |
| if (lpart.isNillable()) |
| flags |= FLAG_PART_NILLABLE; |
| if (lpart.blockExtension()) |
| flags |= FLAG_PART_BLOCKEXT; |
| if (lpart.blockRestriction()) |
| flags |= FLAG_PART_BLOCKREST; |
| if (lpart.blockSubstitution()) |
| flags |= FLAG_PART_BLOCKSUBST; |
| if (lpart.isAbstract()) |
| flags |= FLAG_PART_ABSTRACT; |
| |
| if (lpart instanceof SchemaGlobalElement) |
| { |
| SchemaGlobalElement gpart = (SchemaGlobalElement)lpart; |
| if (gpart.finalExtension()) |
| flags |= FLAG_PART_FINALEXT; |
| if (gpart.finalRestriction()) |
| flags |= FLAG_PART_FINALREST; |
| } |
| } |
| writeShort(flags); |
| writeBigInteger(part.getMinOccurs()); |
| writeBigInteger(part.getMaxOccurs()); |
| writeQNameSet(part.acceptedStartNames()); |
| |
| switch (part.getParticleType()) |
| { |
| case SchemaParticle.WILDCARD: |
| writeQNameSet(part.getWildcardSet()); |
| writeShort(part.getWildcardProcess()); |
| break; |
| |
| case SchemaParticle.ELEMENT: |
| SchemaLocalElement lpart = (SchemaLocalElement)part; |
| writeQName(lpart.getName()); |
| writeType(lpart.getType()); |
| writeString(lpart.getDefaultText()); |
| writeXmlValueObject(lpart.getDefaultValue()); |
| writeSOAPArrayType(((SchemaWSDLArrayType)lpart).getWSDLArrayType()); |
| if (lpart instanceof SchemaGlobalElement) |
| { |
| SchemaGlobalElement gpart = (SchemaGlobalElement)lpart; |
| |
| writeHandle(gpart.substitutionGroup()); |
| |
| QName[] substGroupMembers = gpart.substitutionGroupMembers(); |
| writeShort(substGroupMembers.length); |
| for (int i = 0; i < substGroupMembers.length; i++) |
| writeQName(substGroupMembers[i]); |
| } |
| |
| SchemaIdentityConstraint[] idcs = lpart.getIdentityConstraints(); |
| |
| writeShort(idcs.length); |
| for (int i = 0 ; i < idcs.length ; i++) |
| writeHandle(idcs[i]); |
| |
| break; |
| |
| case SchemaParticle.ALL: |
| case SchemaParticle.SEQUENCE: |
| case SchemaParticle.CHOICE: |
| writeParticleArray(part.getParticleChildren()); |
| break; |
| |
| default: |
| throw new SchemaTypeLoaderException("Unrecognized particle type ", _name, _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE); |
| } |
| } |
| |
| SchemaProperty readPropertyData() |
| { |
| SchemaPropertyImpl prop = new SchemaPropertyImpl(); |
| prop.setName(readQName()); |
| prop.setTypeRef(readTypeRef()); |
| short propflags = readShort(); |
| prop.setAttribute((propflags & FLAG_PROP_ISATTR) != 0); |
| prop.setContainerTypeRef(readTypeRef()); |
| prop.setMinOccurs(readBigInteger()); |
| prop.setMaxOccurs(readBigInteger()); |
| prop.setNillable(readShort()); |
| prop.setDefault(readShort()); |
| prop.setFixed(readShort()); |
| prop.setDefaultText(readString()); |
| |
| prop.setJavaPropertyName(readString()); |
| prop.setJavaTypeCode(readShort()); |
| prop.setExtendsJava(readTypeRef(), |
| (propflags & FLAG_PROP_JAVASINGLETON) != 0, |
| (propflags & FLAG_PROP_JAVAOPTIONAL) != 0, |
| (propflags & FLAG_PROP_JAVAARRAY) != 0); |
| prop.setJavaSetterDelimiter(readQNameSet()); |
| if (atLeast(2, 16, 0)) |
| prop.setDefaultValue(readXmlValueObject()); |
| |
| if (!prop.isAttribute() && atLeast(2, 17, 0)) |
| { |
| short size = readShort(); |
| LinkedHashSet qnames = new LinkedHashSet(size); |
| for (int i = 0 ; i < size ; i++) |
| qnames.add(readQName()); |
| prop.setAcceptedNames(qnames); |
| } |
| prop.setImmutable(); |
| return prop; |
| } |
| |
| void writePropertyData(SchemaProperty prop) |
| { |
| writeQName(prop.getName()); |
| writeType(prop.getType()); |
| writeShort((prop.isAttribute() ? FLAG_PROP_ISATTR : 0) | |
| (prop.extendsJavaSingleton() ? FLAG_PROP_JAVASINGLETON : 0) | |
| (prop.extendsJavaOption() ? FLAG_PROP_JAVAOPTIONAL : 0) | |
| (prop.extendsJavaArray() ? FLAG_PROP_JAVAARRAY : 0)); |
| writeType(prop.getContainerType()); |
| writeBigInteger(prop.getMinOccurs()); |
| writeBigInteger(prop.getMaxOccurs()); |
| writeShort(prop.hasNillable()); |
| writeShort(prop.hasDefault()); |
| writeShort(prop.hasFixed()); |
| writeString(prop.getDefaultText()); |
| |
| writeString(prop.getJavaPropertyName()); |
| writeShort(prop.getJavaTypeCode()); |
| writeType(prop.javaBasedOnType()); |
| writeQNameSet(prop.getJavaSetterDelimiter()); |
| writeXmlValueObject(prop.getDefaultValue()); |
| |
| if (! prop.isAttribute()) |
| { |
| QName[] names = prop.acceptedNames(); |
| writeShort(names.length); |
| for (int i = 0 ; i < names.length ; i++) |
| writeQName(names[i]); |
| } |
| } |
| |
| void writeModelGroupData(SchemaModelGroup grp) |
| { |
| SchemaModelGroupImpl impl = (SchemaModelGroupImpl)grp; |
| writeQName(impl.getName()); |
| writeString(impl.getTargetNamespace()); |
| writeShort(impl.getChameleonNamespace() != null ? 1 : 0); |
| writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15 |
| writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter())); |
| } |
| |
| void writeAttributeGroupData(SchemaAttributeGroup grp) |
| { |
| SchemaAttributeGroupImpl impl = (SchemaAttributeGroupImpl)grp; |
| writeQName(impl.getName()); |
| writeString(impl.getTargetNamespace()); |
| writeShort(impl.getChameleonNamespace() != null ? 1 : 0); |
| writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15 |
| writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter())); |
| } |
| |
| XmlValueRef readXmlValueObject() |
| { |
| SchemaType.Ref typeref = readTypeRef(); |
| if (typeref == null) |
| return null; |
| int btc = readShort(); |
| switch (btc) |
| { |
| default: |
| assert(false); |
| case 0: |
| return new XmlValueRef(typeref, null); |
| case -1: |
| { |
| int size = readShort(); |
| List values = new ArrayList(); |
| writeShort(values.size()); |
| for (int i = 0; i < size; i++) |
| { |
| values.add(readXmlValueObject()); |
| } |
| return new XmlValueRef(typeref, values); |
| } |
| |
| |
| case SchemaType.BTC_ANY_SIMPLE: |
| case SchemaType.BTC_ANY_URI: |
| case SchemaType.BTC_STRING: |
| case SchemaType.BTC_DURATION: |
| case SchemaType.BTC_DATE_TIME: |
| case SchemaType.BTC_TIME: |
| case SchemaType.BTC_DATE: |
| case SchemaType.BTC_G_YEAR_MONTH: |
| case SchemaType.BTC_G_YEAR: |
| case SchemaType.BTC_G_MONTH_DAY: |
| case SchemaType.BTC_G_DAY: |
| case SchemaType.BTC_G_MONTH: |
| case SchemaType.BTC_DECIMAL: |
| case SchemaType.BTC_BOOLEAN: |
| return new XmlValueRef(typeref, readString()); |
| |
| case SchemaType.BTC_BASE_64_BINARY: |
| case SchemaType.BTC_HEX_BINARY: |
| return new XmlValueRef(typeref, readByteArray()); |
| |
| case SchemaType.BTC_QNAME: |
| case SchemaType.BTC_NOTATION: |
| return new XmlValueRef(typeref, readQName()); |
| |
| case SchemaType.BTC_FLOAT: |
| case SchemaType.BTC_DOUBLE: |
| return new XmlValueRef(typeref, new Double(readDouble())); |
| } |
| } |
| |
| void writeXmlValueObject(XmlAnySimpleType value) |
| { |
| SchemaType type = value == null ? null : value.schemaType(); |
| writeType(type); |
| if (type == null) |
| return; |
| |
| SchemaType iType = ((SimpleValue)value).instanceType(); |
| if (iType == null) |
| { |
| writeShort(0); |
| } |
| else if (iType.getSimpleVariety() == SchemaType.LIST) |
| { |
| writeShort(-1); |
| List values = ((XmlObjectBase)value).xgetListValue(); |
| writeShort(values.size()); |
| for (Iterator i = values.iterator(); i.hasNext(); ) |
| { |
| writeXmlValueObject((XmlAnySimpleType)i.next()); |
| } |
| } |
| else |
| { |
| int btc = iType.getPrimitiveType().getBuiltinTypeCode(); |
| writeShort(btc); |
| switch (btc) |
| { |
| case SchemaType.BTC_ANY_SIMPLE: |
| case SchemaType.BTC_ANY_URI: |
| case SchemaType.BTC_STRING: |
| case SchemaType.BTC_DURATION: |
| case SchemaType.BTC_DATE_TIME: |
| case SchemaType.BTC_TIME: |
| case SchemaType.BTC_DATE: |
| case SchemaType.BTC_G_YEAR_MONTH: |
| case SchemaType.BTC_G_YEAR: |
| case SchemaType.BTC_G_MONTH_DAY: |
| case SchemaType.BTC_G_DAY: |
| case SchemaType.BTC_G_MONTH: |
| case SchemaType.BTC_DECIMAL: |
| case SchemaType.BTC_BOOLEAN: |
| writeString(value.getStringValue()); |
| break; |
| |
| case SchemaType.BTC_BASE_64_BINARY: |
| case SchemaType.BTC_HEX_BINARY: |
| writeByteArray(((SimpleValue)value).getByteArrayValue()); |
| break; |
| |
| case SchemaType.BTC_QNAME: |
| case SchemaType.BTC_NOTATION: |
| writeQName(((SimpleValue)value).getQNameValue()); |
| break; |
| |
| case SchemaType.BTC_FLOAT: |
| writeDouble(((SimpleValue)value).getFloatValue()); |
| break; |
| |
| case SchemaType.BTC_DOUBLE: |
| writeDouble(((SimpleValue)value).getDoubleValue()); |
| break; |
| } |
| } |
| } |
| |
| double readDouble() |
| { |
| try |
| { |
| return _input.readDouble(); |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| |
| void writeDouble(double d) |
| { |
| if (_output != null) |
| { |
| try |
| { |
| _output.writeDouble(d); |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| } |
| |
| QNameSet readQNameSet() |
| { |
| short flag = readShort(); |
| |
| Set uriSet = new HashSet(); |
| short uriCount = readShort(); |
| for (int i = 0; i < uriCount; i++) |
| uriSet.add(readString()); |
| |
| Set qnameSet1 = new HashSet(); |
| short qncount1 = readShort(); |
| for (int i = 0; i < qncount1; i++) |
| qnameSet1.add(readQName()); |
| |
| Set qnameSet2 = new HashSet(); |
| short qncount2 = readShort(); |
| for (int i = 0; i < qncount2; i++) |
| qnameSet2.add(readQName()); |
| |
| if (flag == 1) |
| return QNameSet.forSets(uriSet, null, qnameSet1, qnameSet2); |
| else |
| return QNameSet.forSets(null, uriSet, qnameSet2, qnameSet1); |
| } |
| |
| void writeQNameSet(QNameSet set) |
| { |
| boolean invert = (set.excludedURIs() != null); |
| writeShort(invert ? 1 : 0); |
| |
| Set uriSet = invert ? set.excludedURIs() : set.includedURIs(); |
| writeShort(uriSet.size()); |
| for (Iterator i = uriSet.iterator(); i.hasNext(); ) |
| writeString((String)i.next()); |
| |
| Set qnameSet1 = invert ? set.excludedQNamesInIncludedURIs() : set.includedQNamesInExcludedURIs(); |
| writeShort(qnameSet1.size()); |
| for (Iterator i = qnameSet1.iterator(); i.hasNext(); ) |
| writeQName((QName)i.next()); |
| |
| Set qnameSet2 = invert ? set.includedQNamesInExcludedURIs() : set.excludedQNamesInIncludedURIs(); |
| writeShort(qnameSet2.size()); |
| for (Iterator i = qnameSet2.iterator(); i.hasNext(); ) |
| writeQName((QName)i.next()); |
| } |
| |
| byte[] readByteArray() |
| { |
| try |
| { |
| short len = _input.readShort(); |
| byte[] result = new byte[len]; |
| _input.readFully(result); |
| return result; |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| |
| void writeByteArray(byte[] ba) |
| { |
| try |
| { |
| writeShort(ba.length); |
| if (_output != null) |
| _output.write(ba); |
| } |
| catch (IOException e) |
| { |
| throw new SchemaTypeLoaderException(e.getMessage(), _name, _handle, SchemaTypeLoaderException.IO_EXCEPTION); |
| } |
| } |
| |
| BigInteger readBigInteger() |
| { |
| byte[] result = readByteArray(); |
| if (result.length == 0) |
| return null; |
| if (result.length == 1 && result[0] == 0) |
| return BigInteger.ZERO; |
| if (result.length == 1 && result[0] == 1) |
| return BigInteger.ONE; |
| return new BigInteger(result); |
| } |
| |
| void writeBigInteger(BigInteger bi) |
| { |
| if (bi == null) |
| { |
| writeShort(0); |
| } |
| else if (bi.signum() == 0) |
| { |
| writeByteArray(SINGLE_ZERO_BYTE); |
| } |
| else |
| { |
| writeByteArray(bi.toByteArray()); |
| } |
| } |
| |
| } |
| |
| static final byte[] SINGLE_ZERO_BYTE = new byte[] { (byte)0 }; |
| |
| public SchemaType typeForHandle(String handle) |
| { |
| synchronized (_resolvedHandles) |
| { |
| return (SchemaType)_resolvedHandles.get(handle); |
| } |
| } |
| |
| public SchemaType typeForClassname(String classname) |
| { |
| SchemaType.Ref ref = (SchemaType.Ref)_typeRefsByClassname.get(classname); |
| return (ref != null) ? ref.get() : null; |
| } |
| |
| public SchemaComponent resolveHandle(String handle) |
| { |
| SchemaComponent result; |
| |
| synchronized (_resolvedHandles) |
| { |
| result = (SchemaComponent)_resolvedHandles.get(handle); |
| } |
| if (result == null) |
| { |
| XsbReader reader = new XsbReader(handle, -1); |
| int filetype = reader.getActualFiletype(); |
| switch (filetype) |
| { |
| case FILETYPE_SCHEMATYPE: |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving type for handle " + handle, 0); |
| result = reader.finishLoadingType(); |
| break; |
| case FILETYPE_SCHEMAELEMENT: |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving element for handle " + handle, 0); |
| result = reader.finishLoadingElement(); |
| break; |
| case FILETYPE_SCHEMAATTRIBUTE: |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving attribute for handle " + handle, 0); |
| result = reader.finishLoadingAttribute(); |
| break; |
| case FILETYPE_SCHEMAMODELGROUP: |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving model group for handle " + handle, 0); |
| result = reader.finishLoadingModelGroup(); |
| break; |
| case FILETYPE_SCHEMAATTRIBUTEGROUP: |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving attribute group for handle " + handle, 0); |
| result = reader.finishLoadingAttributeGroup(); |
| break; |
| case FILETYPE_SCHEMAIDENTITYCONSTRAINT: |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving id constraint for handle " + handle, 0); |
| result = reader.finishLoadingIdentityConstraint(); |
| break; |
| default: |
| throw new IllegalStateException("Illegal handle type"); |
| } |
| |
| synchronized (_resolvedHandles) |
| { |
| if (!_resolvedHandles.containsKey(handle)) |
| _resolvedHandles.put(handle, result); |
| else |
| result = (SchemaComponent)_resolvedHandles.get(handle); |
| } |
| } |
| return result; |
| } |
| |
| private final Map _resolvedHandles = new HashMap(); |
| private boolean _allNonGroupHandlesResolved = false; |
| |
| public void resolve() |
| { |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolve called type system " + _name, 0); |
| if (_allNonGroupHandlesResolved) |
| return; |
| |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Resolving all handles for type system " + _name, 1); |
| |
| List refs = new ArrayList(); |
| refs.addAll(_globalElements.values()); |
| refs.addAll(_globalAttributes.values()); |
| refs.addAll(_globalTypes.values()); |
| refs.addAll(_documentTypes.values()); |
| refs.addAll(_attributeTypes.values()); |
| refs.addAll(_identityConstraints.values()); |
| |
| for (Iterator i = refs.iterator(); i.hasNext(); ) |
| { |
| SchemaComponent.Ref ref = (SchemaComponent.Ref)i.next(); |
| ref.getComponent(); // Forces ref to be resolved |
| } |
| |
| XBeanDebug.trace(XBeanDebug.TRACE_SCHEMA_LOADING, "Finished resolving type system " + _name, -1); |
| _allNonGroupHandlesResolved = true; |
| } |
| |
| |
| public boolean isNamespaceDefined(String namespace) |
| { |
| return _namespaces.contains(namespace); |
| } |
| |
| public SchemaType.Ref findTypeRef(QName name) |
| { |
| return (SchemaType.Ref)_globalTypes.get(name); |
| } |
| |
| public SchemaType.Ref findDocumentTypeRef(QName name) |
| { |
| return (SchemaType.Ref)_documentTypes.get(name); |
| } |
| |
| public SchemaType.Ref findAttributeTypeRef(QName name) |
| { |
| return (SchemaType.Ref)_attributeTypes.get(name); |
| } |
| |
| public SchemaGlobalElement.Ref findElementRef(QName name) |
| { |
| return (SchemaGlobalElement.Ref)_globalElements.get(name); |
| } |
| |
| public SchemaGlobalAttribute.Ref findAttributeRef(QName name) |
| { |
| return (SchemaGlobalAttribute.Ref)_globalAttributes.get(name); |
| } |
| |
| public SchemaModelGroup.Ref findModelGroupRef(QName name) |
| { |
| return (SchemaModelGroup.Ref)_modelGroups.get(name); |
| } |
| |
| public SchemaAttributeGroup.Ref findAttributeGroupRef(QName name) |
| { |
| return (SchemaAttributeGroup.Ref)_attributeGroups.get(name); |
| } |
| |
| public SchemaIdentityConstraint.Ref findIdentityConstraintRef(QName name) |
| { |
| return (SchemaIdentityConstraint.Ref)_identityConstraints.get(name); |
| } |
| |
| public SchemaType[] globalTypes() |
| { |
| if (_globalTypes.isEmpty()) |
| return EMPTY_ST_ARRAY; |
| |
| SchemaType[] result = new SchemaType[_globalTypes.size()]; |
| int j = 0; |
| for (Iterator i = _globalTypes.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaType.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaType[] redefinedGlobalTypes() |
| { |
| if (_redefinedGlobalTypes.isEmpty()) |
| return EMPTY_ST_ARRAY; |
| |
| SchemaType[] result = new SchemaType[_redefinedGlobalTypes.size()]; |
| int j = 0; |
| for (Iterator i = _redefinedGlobalTypes.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaType.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public InputStream getSourceAsStream(String sourceName) |
| { |
| if (!sourceName.startsWith("/")) |
| sourceName = "/" + sourceName; |
| |
| return _resourceLoader.getResourceAsStream("schema/src" + sourceName); |
| } |
| |
| public SchemaType[] documentTypes() |
| { |
| if (_documentTypes.isEmpty()) |
| return EMPTY_ST_ARRAY; |
| |
| SchemaType[] result = new SchemaType[_documentTypes.size()]; |
| int j = 0; |
| for (Iterator i = _documentTypes.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaType.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaType[] attributeTypes() |
| { |
| if (_attributeTypes.isEmpty()) |
| return EMPTY_ST_ARRAY; |
| |
| SchemaType[] result = new SchemaType[_attributeTypes.size()]; |
| int j = 0; |
| for (Iterator i = _attributeTypes.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaType.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaGlobalElement[] globalElements() |
| { |
| if (_globalElements.isEmpty()) |
| return EMPTY_GE_ARRAY; |
| |
| SchemaGlobalElement[] result = new SchemaGlobalElement[_globalElements.size()]; |
| int j = 0; |
| for (Iterator i = _globalElements.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaGlobalElement.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaGlobalAttribute[] globalAttributes() |
| { |
| if (_globalAttributes.isEmpty()) |
| return EMPTY_GA_ARRAY; |
| |
| SchemaGlobalAttribute[] result = new SchemaGlobalAttribute[_globalAttributes.size()]; |
| int j = 0; |
| for (Iterator i = _globalAttributes.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaGlobalAttribute.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaModelGroup[] modelGroups() |
| { |
| if (_modelGroups.isEmpty()) |
| return EMPTY_MG_ARRAY; |
| |
| SchemaModelGroup[] result = new SchemaModelGroup[_modelGroups.size()]; |
| int j = 0; |
| for (Iterator i = _modelGroups.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaModelGroup.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaModelGroup[] redefinedModelGroups() |
| { |
| if (_redefinedModelGroups.isEmpty()) |
| return EMPTY_MG_ARRAY; |
| |
| SchemaModelGroup[] result = new SchemaModelGroup[_redefinedModelGroups.size()]; |
| int j = 0; |
| for (Iterator i = _redefinedModelGroups.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaModelGroup.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaAttributeGroup[] attributeGroups() |
| { |
| if (_attributeGroups.isEmpty()) |
| return EMPTY_AG_ARRAY; |
| |
| SchemaAttributeGroup[] result = new SchemaAttributeGroup[_attributeGroups.size()]; |
| int j = 0; |
| for (Iterator i = _attributeGroups.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaAttributeGroup.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaAttributeGroup[] redefinedAttributeGroups() |
| { |
| if (_redefinedAttributeGroups.isEmpty()) |
| return EMPTY_AG_ARRAY; |
| |
| SchemaAttributeGroup[] result = new SchemaAttributeGroup[_redefinedAttributeGroups.size()]; |
| int j = 0; |
| for (Iterator i = _redefinedAttributeGroups.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaAttributeGroup.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public SchemaIdentityConstraint[] identityConstraints() |
| { |
| if (_identityConstraints.isEmpty()) |
| return EMPTY_IC_ARRAY; |
| |
| SchemaIdentityConstraint[] result = new SchemaIdentityConstraint[_identityConstraints.size()]; |
| int j = 0; |
| for (Iterator i = _identityConstraints.values().iterator(); i.hasNext(); j++) |
| result[j] = ((SchemaIdentityConstraint.Ref)i.next()).get(); |
| return result; |
| } |
| |
| public ClassLoader getClassLoader() |
| { |
| return _classloader; |
| } |
| |
| /** |
| * Used INTERNALLY ONLY by the code generator AFTER the type system has |
| * been saved and a handle has been established for each type. |
| */ |
| public String handleForType(SchemaType type) |
| { |
| return _localHandles.handleForType(type); |
| } |
| |
| public String getName() |
| { |
| return _name; |
| } |
| |
| public SchemaTypeSystem typeSystemForName(String name) |
| { |
| if (_name != null && name.equals(_name)) |
| return this; |
| return null; |
| } |
| } |
| |