| /* Copyright 2004 The Apache Software Foundation |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.xmlbeans.impl.schema; |
| |
| import org.apache.xmlbeans.*; |
| import org.apache.xmlbeans.impl.common.QNameHelper; |
| import org.apache.xmlbeans.impl.util.LongUTFDataInputStream; |
| import org.apache.xmlbeans.impl.util.LongUTFDataOutputStream; |
| import org.apache.xmlbeans.impl.values.XmlObjectBase; |
| import org.apache.xmlbeans.impl.xb.xsdschema.AttributeGroupDocument; |
| import org.apache.xmlbeans.impl.xb.xsdschema.GroupDocument; |
| import org.apache.xmlbeans.soap.SOAPArrayType; |
| import org.apache.xmlbeans.soap.SchemaWSDLArrayType; |
| |
| import javax.xml.namespace.QName; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.math.BigInteger; |
| import java.util.*; |
| |
| import static org.apache.xmlbeans.impl.schema.SchemaTypeSystemImpl.*; |
| |
| class XsbReader { |
| |
| // MAX_UNSIGNED_SHORT |
| private static final int MAX_UNSIGNED_SHORT = Short.MAX_VALUE * 2 + 1; |
| |
| private final SchemaTypeSystemImpl typeSystem; |
| private LongUTFDataInputStream _input; |
| private LongUTFDataOutputStream _output; |
| private SchemaTypeSystemImpl.StringPool _stringPool; |
| private String _handle; |
| private int _majorver; |
| private int _minorver; |
| private int _releaseno; |
| int _actualfiletype; |
| |
| XsbReader(SchemaTypeSystemImpl typeSystem, String handle) { |
| this.typeSystem = typeSystem; |
| _handle = handle; |
| _stringPool = new SchemaTypeSystemImpl.StringPool(_handle, typeSystem.getName()); |
| } |
| |
| public XsbReader(SchemaTypeSystemImpl typeSystem, String handle, int filetype) { |
| this.typeSystem = typeSystem; |
| String resourcename = typeSystem.getBasePackage() + handle + ".xsb"; |
| InputStream rawinput = typeSystem.getLoaderStream(resourcename); |
| if (rawinput == null) { |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Could not locate compiled schema resource " + resourcename, typeSystem.getName(), handle, SchemaTypeLoaderException.NO_RESOURCE); |
| } |
| |
| _input = new LongUTFDataInputStream(rawinput); |
| _handle = handle; |
| |
| int magic = readInt(); |
| if (magic != DATA_BABE) { |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: Wrong magic cookie", typeSystem.getName(), 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, typeSystem.getName(), 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, typeSystem.getName(), 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, typeSystem.getName(), handle, SchemaTypeLoaderException.WRONG_MINOR_VERSION); |
| } |
| |
| if (atLeast(2, 18, 0)) { |
| _releaseno = readShort(); |
| } |
| |
| int actualfiletype = readShort(); |
| if (actualfiletype != filetype && filetype != 0xFFFF) { |
| throw new SchemaTypeLoaderException("XML-BEANS compiled schema: File has the wrong type - expecting type " + filetype + ", got type " + actualfiletype, typeSystem.getName(), handle, SchemaTypeLoaderException.WRONG_FILE_TYPE); |
| } |
| |
| _stringPool = new SchemaTypeSystemImpl.StringPool(_handle, typeSystem.getName()); |
| _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; |
| } |
| |
| 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 = typeSystem.getBasePackage() + handle + ".xsb"; |
| } |
| |
| OutputStream rawoutput = typeSystem.getSaverStream(resourcename, _handle); |
| if (rawoutput == null) { |
| throw new SchemaTypeLoaderException("Could not write compiled schema resource " + resourcename, typeSystem.getName(), handle, SchemaTypeLoaderException.NOT_WRITEABLE); |
| } |
| |
| _output = new LongUTFDataOutputStream(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(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| _output = null; |
| _stringPool = null; |
| _handle = null; |
| } |
| |
| void writeIndexData() { |
| // has a handle pool (count, handle/type, handle/type...) |
| typeSystem.getTypePool().writeHandlePool(this); |
| |
| // then a qname map of global elements (count, qname/handle, qname/handle...) |
| writeQNameMap(typeSystem.globalElements()); |
| |
| // qname map of global attributes |
| writeQNameMap(typeSystem.globalAttributes()); |
| |
| // qname map of model groups |
| writeQNameMap(typeSystem.modelGroups()); |
| |
| // qname map of attribute groups |
| writeQNameMap(typeSystem.attributeGroups()); |
| |
| // qname map of identity constraints |
| writeQNameMap(typeSystem.identityConstraints()); |
| |
| // qname map of global types |
| writeQNameMap(typeSystem.globalTypes()); |
| |
| // qname map of document types, by the qname of the contained element |
| writeDocumentTypeMap(typeSystem.documentTypes()); |
| |
| // qname map of attribute types, by the qname of the contained attribute |
| writeAttributeTypeMap(typeSystem.attributeTypes()); |
| |
| // all the types by classname |
| writeClassnameMap(typeSystem.getTypeRefsByClassname()); |
| |
| // all the namespaces |
| writeNamespaces(typeSystem.getNamespaces()); |
| |
| // VERSION 2.15 and newer below |
| writeQNameMap(typeSystem.redefinedGlobalTypes()); |
| writeQNameMap(typeSystem.redefinedModelGroups()); |
| writeQNameMap(typeSystem.redefinedAttributeGroups()); |
| writeAnnotations(typeSystem.annotations()); |
| } |
| |
| int readShort() { |
| try { |
| return _input.readUnsignedShort(); |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| |
| void writeShort(int s) { |
| if (s >= MAX_UNSIGNED_SHORT || s < -1) { |
| throw new SchemaTypeLoaderException("Value " + s + " out of range: must fit in a 16-bit unsigned short.", typeSystem.getName(), _handle, SchemaTypeLoaderException.INT_TOO_LARGE); |
| } |
| if (_output != null) { |
| try { |
| _output.writeShort(s); |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| } |
| |
| int readUnsignedShortOrInt() { |
| try { |
| return _input.readUnsignedShortOrInt(); |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| |
| void writeShortOrInt(int s) { |
| if (_output != null) { |
| try { |
| _output.writeShortOrInt(s); |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| } |
| |
| int readInt() { |
| try { |
| return _input.readInt(); |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| |
| void writeInt(int i) { |
| if (_output != null) { |
| try { |
| _output.writeInt(i); |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| } |
| |
| String readString() { |
| int code = readUnsignedShortOrInt(); |
| return _stringPool.stringForCode(code); |
| } |
| |
| void writeString(String str) { |
| int code = _stringPool.codeForString(str); |
| writeShortOrInt(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()); |
| } |
| } |
| |
| void writeAnnotation(SchemaAnnotation a) { |
| // Write attributes |
| if (a == null) { |
| writeInt(-1); |
| return; |
| } |
| SchemaAnnotation.Attribute[] attributes = a.getAttributes(); |
| writeInt(attributes.length); |
| for (SchemaAnnotation.Attribute attribute : attributes) { |
| QName name = attribute.getName(); |
| String value = attribute.getValue(); |
| String valueURI = attribute.getValueUri(); |
| writeQName(name); |
| writeString(value); |
| writeString(valueURI); |
| } |
| |
| // Write documentation items |
| XmlObject[] documentationItems = a.getUserInformation(); |
| writeInt(documentationItems.length); |
| XmlOptions opt = new XmlOptions().setSaveOuter().setSaveAggressiveNamespaces(); |
| for (XmlObject doc : documentationItems) { |
| writeString(doc.xmlText(opt)); |
| } |
| |
| // Write application info items |
| XmlObject[] appInfoItems = a.getApplicationInformation(); |
| writeInt(appInfoItems.length); |
| for (XmlObject doc : appInfoItems) { |
| writeString(doc.xmlText(opt)); |
| } |
| } |
| |
| SchemaAnnotation readAnnotation(SchemaContainer c) { |
| if (!atLeast(2, 19, 0)) { |
| return null; // no annotations for this version of the file |
| } |
| // Read attributes |
| int n = readInt(); |
| if (n == -1) { |
| return null; |
| } |
| SchemaAnnotation.Attribute[] attributes = |
| new SchemaAnnotation.Attribute[n]; |
| for (int i = 0; i < n; i++) { |
| QName name = readQName(); |
| String value = readString(); |
| String valueUri = null; |
| if (atLeast(2, 24, 0)) { |
| valueUri = readString(); |
| } |
| attributes[i] = new SchemaAnnotationImpl.AttributeImpl(name, value, valueUri); |
| } |
| |
| // Read documentation items |
| n = readInt(); |
| String[] docStrings = new String[n]; |
| for (int i = 0; i < n; i++) { |
| docStrings[i] = readString(); |
| } |
| |
| // Read application info items |
| n = readInt(); |
| String[] appInfoStrings = new String[n]; |
| for (int i = 0; i < n; i++) { |
| appInfoStrings[i] = readString(); |
| } |
| |
| return new SchemaAnnotationImpl(c, appInfoStrings, |
| docStrings, attributes); |
| } |
| |
| void writeAnnotations(SchemaAnnotation[] anns) { |
| writeInt(anns.length); |
| for (SchemaAnnotation ann : anns) { |
| writeAnnotation(ann); |
| } |
| } |
| |
| List<SchemaAnnotation> readAnnotations() { |
| int n = readInt(); |
| List<SchemaAnnotation> result = new ArrayList<>(n); |
| // BUGBUG(radup) |
| SchemaContainer container = typeSystem.getContainerNonNull(""); |
| for (int i = 0; i < n; i++) { |
| result.add(readAnnotation(container)); |
| } |
| return result; |
| } |
| |
| SchemaComponent.Ref readHandle() { |
| String handle = readString(); |
| if (handle == null) { |
| return null; |
| } |
| |
| if (handle.charAt(0) != '_') { |
| return typeSystem.getTypePool().refForHandle(handle); |
| } |
| |
| switch (handle.charAt(2)) { |
| case 'I': // _BI_ - built-in schema type system |
| SchemaType st = (SchemaType) BuiltinSchemaTypeSystem.get().resolveHandle(handle); |
| if (st != null) { |
| return st.getRef(); |
| } |
| st = (SchemaType) XQuerySchemaTypeSystem.get().resolveHandle(handle); |
| return st.getRef(); |
| case 'T': // _XT_ - external type |
| return typeSystem.getLinker().findTypeRef(QNameHelper.forPretty(handle, 4)); |
| case 'E': // _XE_ - external element |
| return typeSystem.getLinker().findElementRef(QNameHelper.forPretty(handle, 4)); |
| case 'A': // _XA_ - external attribute |
| return typeSystem.getLinker().findAttributeRef(QNameHelper.forPretty(handle, 4)); |
| case 'M': // _XM_ - external model group |
| return typeSystem.getLinker().findModelGroupRef(QNameHelper.forPretty(handle, 4)); |
| case 'N': // _XN_ - external attribute group |
| return typeSystem.getLinker().findAttributeGroupRef(QNameHelper.forPretty(handle, 4)); |
| case 'D': // _XD_ - external identity constraint |
| return typeSystem.getLinker().findIdentityConstraintRef(QNameHelper.forPretty(handle, 4)); |
| case 'R': // _XR_ - external ref to attribute's type |
| // deprecated: replaced by _XY_ |
| SchemaGlobalAttribute attr = typeSystem.getLinker().findAttribute(QNameHelper.forPretty(handle, 4)); |
| if (attr == null) { |
| throw new SchemaTypeLoaderException("Cannot resolve attribute for handle " + handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE); |
| } |
| return attr.getType().getRef(); |
| case 'S': // _XS_ - external ref to element's type |
| // deprecated: replaced by _XY_ |
| SchemaGlobalElement elem = typeSystem.getLinker().findElement(QNameHelper.forPretty(handle, 4)); |
| if (elem == null) { |
| throw new SchemaTypeLoaderException("Cannot resolve element for handle " + handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE); |
| } |
| return elem.getType().getRef(); |
| case 'O': // _XO_ - external ref to document type |
| return typeSystem.getLinker().findDocumentTypeRef(QNameHelper.forPretty(handle, 4)); |
| case 'Y': // _XY_ - external ref to any possible type |
| SchemaType type = typeSystem.getLinker().typeForSignature(handle.substring(4)); |
| if (type == null) { |
| throw new SchemaTypeLoaderException("Cannot resolve type for handle " + handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE); |
| } |
| return type.getRef(); |
| default: |
| throw new SchemaTypeLoaderException("Cannot resolve handle " + handle, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE); |
| } |
| } |
| |
| void writeHandle(SchemaComponent comp) { |
| if (comp == null || comp.getTypeSystem() == typeSystem) { |
| writeString(typeSystem.getTypePool().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 |
| // kkrouse 02/1/2005: _XR_ and _XS_ refs are replaced by _XY_ |
| if (type.getName() != null) { |
| writeString("_XT_" + QNameHelper.pretty(type.getName())); |
| } else if (type.isDocumentType()) { |
| // Substitution groups will create document types that |
| // extend from other document types, possibly in |
| // different jars |
| writeString("_XO_" + QNameHelper.pretty(type.getDocumentElementName())); |
| } else { |
| // fix for XMLBEANS-105: |
| // save out the external type reference using the type's signature. |
| writeString("_XY_" + type); |
| } |
| |
| return; |
| |
| default: |
| assert (false); |
| throw new SchemaTypeLoaderException("Cannot write handle for component " + comp, typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_HANDLE); |
| } |
| } |
| |
| SchemaType.Ref readTypeRef() { |
| return (SchemaType.Ref) readHandle(); |
| } |
| |
| void writeType(SchemaType type) { |
| writeHandle(type); |
| } |
| |
| Map<QName, SchemaComponent.Ref> readQNameRefMap() { |
| Map<QName, SchemaComponent.Ref> 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; |
| } |
| |
| List<SchemaComponent.Ref> readQNameRefMapAsList(List<QName> names) { |
| int size = readShort(); |
| List<SchemaComponent.Ref> result = new ArrayList<>(size); |
| for (int i = 0; i < size; i++) { |
| QName name = readQName(); |
| SchemaComponent.Ref obj = readHandle(); |
| result.add(obj); |
| names.add(name); |
| } |
| return result; |
| } |
| |
| void writeQNameMap(SchemaComponent[] components) { |
| writeShort(components.length); |
| for (SchemaComponent component : components) { |
| writeQName(component.getName()); |
| writeHandle(component); |
| } |
| } |
| |
| void writeDocumentTypeMap(SchemaType[] doctypes) { |
| writeShort(doctypes.length); |
| for (SchemaType doctype : doctypes) { |
| writeQName(doctype.getDocumentElementName()); |
| writeHandle(doctype); |
| } |
| } |
| |
| void writeAttributeTypeMap(SchemaType[] attrtypes) { |
| writeShort(attrtypes.length); |
| for (SchemaType attrtype : attrtypes) { |
| writeQName(attrtype.getAttributeTypeAttributeName()); |
| writeHandle(attrtype); |
| } |
| } |
| |
| 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 (SchemaType schemaType : array) { |
| writeHandle(schemaType); |
| } |
| } |
| |
| Map<String, SchemaComponent.Ref> readClassnameRefMap() { |
| Map<String, SchemaComponent.Ref> 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<String, SchemaComponent.Ref> typesByClass) { |
| writeShort(typesByClass.size()); |
| typesByClass.forEach((className, ref) -> { |
| writeString(className); |
| writeHandle(((SchemaType.Ref) ref).get()); |
| }); |
| } |
| |
| Set<String> readNamespaces() { |
| Set<String> result = new HashSet<>(); |
| int size = readShort(); |
| for (int i = 0; i < size; i++) { |
| String ns = readString(); |
| result.add(ns); |
| } |
| return result; |
| } |
| |
| void writeNamespaces(Set<String> namespaces) { |
| writeShort(namespaces.size()); |
| namespaces.forEach(this::writeString); |
| } |
| |
| void checkContainerNotNull(SchemaContainer container, QName name) { |
| if (container == null) { |
| throw new LinkageError("Loading of resource " + name + '.' + _handle + |
| "failed, information from " + name + ".index.xsb is " + |
| " out of sync (or conflicting index files found)"); |
| } |
| } |
| |
| /** |
| * Finishes loading an element after the header has already been loaded. |
| */ |
| public SchemaGlobalElement finishLoadingElement() { |
| try { |
| int particleType = readShort(); |
| if (particleType != SchemaParticle.ELEMENT) { |
| throw new SchemaTypeLoaderException("Wrong particle type ", typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE); |
| } |
| int particleFlags = readShort(); |
| BigInteger minOccurs = readBigInteger(); |
| BigInteger maxOccurs = readBigInteger(); |
| QNameSet transitionRules = readQNameSet(); |
| QName name = readQName(); |
| SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI()); |
| checkContainerNotNull(container, name); |
| SchemaGlobalElementImpl impl = new SchemaGlobalElementImpl(container); |
| impl.setParticleType(particleType); |
| impl.setMinOccurs(minOccurs); |
| impl.setMaxOccurs(maxOccurs); |
| impl.setTransitionRules(transitionRules, |
| (particleFlags & FLAG_PART_SKIPPABLE) != 0); |
| impl.setNameAndTypeRef(name, readTypeRef()); |
| impl.setDefault(readString(), (particleFlags & FLAG_PART_FIXED) != 0, null); |
| if (atLeast(2, 16, 0)) { |
| impl.setDefaultValue(readXmlValueObject()); |
| } |
| impl.setNillable((particleFlags & FLAG_PART_NILLABLE) != 0); |
| impl.setBlock((particleFlags & FLAG_PART_BLOCKEXT) != 0, |
| (particleFlags & FLAG_PART_BLOCKREST) != 0, |
| (particleFlags & FLAG_PART_BLOCKSUBST) != 0); |
| impl.setWsdlArrayType(readSOAPArrayType()); |
| impl.setAbstract((particleFlags & FLAG_PART_ABSTRACT) != 0); |
| impl.setAnnotation(readAnnotation(container)); |
| impl.setFinal( |
| (particleFlags & FLAG_PART_FINALEXT) != 0, |
| (particleFlags & FLAG_PART_FINALREST) != 0); |
| |
| if (atLeast(2, 17, 0)) { |
| impl.setSubstitutionGroup((SchemaGlobalElement.Ref) readHandle()); |
| } |
| |
| int substGroupCount = readShort(); |
| for (int i = 0; i < substGroupCount; i++) { |
| impl.addSubstitutionGroupMember(readQName()); |
| } |
| SchemaIdentityConstraint.Ref[] idcs = new SchemaIdentityConstraint.Ref[readShort()]; |
| |
| for (int i = 0; i < idcs.length; i++) { |
| idcs[i] = (SchemaIdentityConstraint.Ref) readHandle(); |
| } |
| |
| impl.setIdentityConstraints(idcs); |
| impl.setFilename(readString()); |
| return impl; |
| } catch (SchemaTypeLoaderException e) { |
| throw e; |
| } catch (Exception e) { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), null, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } finally { |
| readEnd(); |
| } |
| } |
| |
| public SchemaGlobalAttribute finishLoadingAttribute() { |
| try { |
| QName name = readQName(); |
| SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI()); |
| checkContainerNotNull(container, name); |
| SchemaGlobalAttributeImpl impl = new SchemaGlobalAttributeImpl(container); |
| loadAttribute(impl, name, container); |
| impl.setFilename(readString()); |
| |
| return impl; |
| } catch (SchemaTypeLoaderException e) { |
| throw e; |
| } catch (Exception e) { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } finally { |
| readEnd(); |
| } |
| } |
| |
| SchemaModelGroup finishLoadingModelGroup() { |
| QName name = readQName(); |
| SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI()); |
| checkContainerNotNull(container, name); |
| SchemaModelGroupImpl impl = new SchemaModelGroupImpl(container); |
| |
| try { |
| impl.init(name, readString(), readShort() == 1, |
| atLeast(2, 22, 0) ? readString() : null, |
| atLeast(2, 22, 0) ? readString() : null, |
| atLeast(2, 15, 0) && readShort() == 1, |
| GroupDocument.Factory.parse(readString()).getGroup(), readAnnotation(container), null); |
| if (atLeast(2, 21, 0)) { |
| impl.setFilename(readString()); |
| } |
| return impl; |
| } catch (SchemaTypeLoaderException e) { |
| throw e; |
| } catch (Exception e) { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } finally { |
| readEnd(); |
| } |
| } |
| |
| SchemaIdentityConstraint finishLoadingIdentityConstraint() { |
| try { |
| QName name = readQName(); |
| SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI()); |
| checkContainerNotNull(container, name); |
| SchemaIdentityConstraintImpl impl = new SchemaIdentityConstraintImpl(container); |
| impl.setName(name); |
| impl.setConstraintCategory(readShort()); |
| impl.setSelector(readString()); |
| impl.setAnnotation(readAnnotation(container)); |
| |
| 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<String, String> nsMappings = new HashMap<>(); |
| for (int i = 0; i < mapCount; i++) { |
| String prefix = readString(); |
| String uri = readString(); |
| nsMappings.put(prefix, uri); |
| } |
| impl.setNSMap(nsMappings); |
| |
| if (atLeast(2, 21, 0)) { |
| impl.setFilename(readString()); |
| } |
| |
| return impl; |
| } catch (SchemaTypeLoaderException e) { |
| throw e; |
| } catch (Exception e) { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } finally { |
| readEnd(); |
| } |
| } |
| |
| SchemaAttributeGroup finishLoadingAttributeGroup() { |
| QName name = readQName(); |
| SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI()); |
| checkContainerNotNull(container, name); |
| SchemaAttributeGroupImpl impl = new SchemaAttributeGroupImpl(container); |
| |
| try { |
| impl.init(name, readString(), readShort() == 1, |
| atLeast(2, 22, 0) ? readString() : null, |
| atLeast(2, 15, 0) && readShort() == 1, |
| AttributeGroupDocument.Factory.parse(readString()).getAttributeGroup(), |
| readAnnotation(container), null); |
| if (atLeast(2, 21, 0)) { |
| impl.setFilename(readString()); |
| } |
| return impl; |
| } catch (SchemaTypeLoaderException e) { |
| throw e; |
| } catch (Exception e) { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _handle, SchemaTypeLoaderException.NESTED_EXCEPTION, e); |
| } finally { |
| readEnd(); |
| } |
| } |
| |
| public SchemaType finishLoadingType() { |
| try { |
| SchemaContainer cNonNull = typeSystem.getContainerNonNull(""); //HACKHACK |
| SchemaTypeImpl impl = new SchemaTypeImpl(cNonNull, true); |
| impl.setName(readQName()); |
| impl.setOuterSchemaTypeRef(readTypeRef()); |
| impl.setBaseDepth(readShort()); |
| impl.setBaseTypeRef(readTypeRef()); |
| impl.setDerivationType(readShort()); |
| impl.setAnnotation(readAnnotation(null)); |
| |
| 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; |
| } |
| // TODO (radup) find the right solution here |
| String jn = readString(); |
| impl.setFullJavaName(jn == null ? "" : jn); |
| jn = readString(); |
| impl.setFullJavaImplName(jn == null ? "" : jn); |
| |
| 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); |
| |
| int 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); |
| |
| if (atLeast(2, 23, 0)) { |
| impl.setContentBasedOnTypeRef(readTypeRef()); |
| } |
| |
| // Attribute Model Table |
| SchemaAttributeModelImpl attrModel = new SchemaAttributeModelImpl(); |
| |
| int attrCount = readShort(); |
| for (int i = 0; i < attrCount; i++) { |
| attrModel.addAttribute(readAttributeData()); |
| } |
| |
| attrModel.setWildcardSet(readQNameSet()); |
| attrModel.setWildcardProcess(readShort()); |
| |
| // Attribute Property Table |
| Map<QName, SchemaProperty> attrProperties = new LinkedHashMap<>(); |
| int 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", typeSystem.getName(), _handle, SchemaTypeLoaderException.WRONG_PROPERTY_TYPE); |
| } |
| attrProperties.put(prop.getName(), prop); |
| } |
| |
| SchemaParticle contentModel = null; |
| Map<QName, SchemaProperty> elemProperties = null; |
| int 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", typeSystem.getName(), _handle, SchemaTypeLoaderException.MALFORMED_CONTENT_MODEL); |
| } |
| |
| // Element Property Table |
| |
| elemProperties = new LinkedHashMap<>(); |
| int 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", typeSystem.getName(), _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) { |
| int 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]; |
| int facetCount = readShort(); |
| for (int i = 0; i < facetCount; i++) { |
| int facetCode = readShort(); |
| facets[facetCode] = readXmlValueObject(); |
| fixedFacets[facetCode] = (readShort() == 1); |
| } |
| impl.setBasicFacets(facets, fixedFacets); |
| |
| impl.setWhiteSpaceRule(readShort()); |
| |
| impl.setPatternFacet((flags & FLAG_HAS_PATTERN) != 0); |
| |
| int 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); |
| |
| int 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) { |
| int seCount = readUnsignedShortOrInt(); |
| 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", typeSystem.getName(), _handle, SchemaTypeLoaderException.WRONG_SIMPLE_VARIETY); |
| } |
| } |
| |
| impl.setFilename(readString()); |
| // Set the container for global, attribute or document types |
| if (impl.getName() != null) { |
| SchemaContainer container = typeSystem.getContainer(impl.getName().getNamespaceURI()); |
| checkContainerNotNull(container, impl.getName()); |
| impl.setContainer(container); |
| } else if (impl.isDocumentType()) { |
| QName name = impl.getDocumentElementName(); |
| if (name != null) { |
| SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI()); |
| checkContainerNotNull(container, name); |
| impl.setContainer(container); |
| } |
| } else if (impl.isAttributeType()) { |
| QName name = impl.getAttributeTypeAttributeName(); |
| if (name != null) { |
| SchemaContainer container = typeSystem.getContainer(name.getNamespaceURI()); |
| checkContainerNotNull(container, name); |
| impl.setContainer(container); |
| } |
| } |
| |
| return impl; |
| } catch (SchemaTypeLoaderException e) { |
| throw e; |
| } catch (Exception e) { |
| throw new SchemaTypeLoaderException("Cannot load type from typesystem", typeSystem.getName(), _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()); |
| writeAnnotation(type.getAnnotation()); |
| 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()); |
| |
| writeType(type.getContentBasedOnType()); |
| |
| // Attribute Model Table |
| SchemaAttributeModel attrModel = type.getAttributeModel(); |
| SchemaLocalAttribute[] attrs = attrModel.getAttributes(); |
| |
| writeShort(attrs.length); |
| for (SchemaLocalAttribute attr : attrs) { |
| writeAttributeData(attr); |
| } |
| |
| writeQNameSet(attrModel.getWildcardSet()); |
| writeShort(attrModel.getWildcardProcess()); |
| |
| // Attribute Property Table |
| SchemaProperty[] attrProperties = type.getAttributeProperties(); |
| writeShort(attrProperties.length); |
| for (SchemaProperty attrProperty : attrProperties) { |
| writePropertyData(attrProperty); |
| } |
| |
| 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 (SchemaProperty eltProperty : eltProperties) { |
| writePropertyData(eltProperty); |
| } |
| } |
| } |
| |
| 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 (org.apache.xmlbeans.impl.regex.RegularExpression pattern : patterns) { |
| writeString(pattern.getPattern()); |
| } |
| |
| XmlAnySimpleType[] enumValues = type.getEnumerationValues(); |
| if (enumValues == null) { |
| writeShort(0); |
| } else { |
| writeShortOrInt(enumValues.length); |
| for (XmlAnySimpleType enumValue : enumValues) { |
| writeXmlValueObject(enumValue); |
| } |
| } |
| |
| // new for version 2.3 |
| writeType(type.getBaseEnumType()); |
| if (type.hasStringEnumValues()) { |
| SchemaStringEnumEntry[] entries = type.getStringEnumEntries(); |
| writeShort(entries.length); |
| for (SchemaStringEnumEntry entry : entries) { |
| writeString(entry.getString()); |
| writeShort(entry.getIntValue()); |
| writeString(entry.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, readQName(), null); |
| return result; |
| } |
| |
| |
| void loadAttribute(SchemaLocalAttributeImpl result, QName name, SchemaContainer container) { |
| // name, type, use, deftext, defval, fixed, soaparraytype, annotation |
| result.init(name, readTypeRef(), readShort(), readString(), null, atLeast(2, 16, 0) ? readXmlValueObject() : null, readShort() == 1, readSOAPArrayType(), readAnnotation(container), null); |
| } |
| |
| 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()); |
| writeAnnotation(attr.getAnnotation()); |
| } |
| |
| void writeIdConstraintData(SchemaIdentityConstraint idc) { |
| writeQName(idc.getName()); |
| writeShort(idc.getConstraintCategory()); |
| writeString(idc.getSelector()); |
| writeAnnotation(idc.getAnnotation()); |
| |
| String[] fields = idc.getFields(); |
| writeShort(fields.length); |
| for (String field : fields) { |
| writeString(field); |
| } |
| |
| |
| if (idc.getConstraintCategory() == SchemaIdentityConstraint.CC_KEYREF) { |
| writeHandle(idc.getReferencedKey()); |
| } |
| |
| Map<String, String> mappings = idc.getNSMap(); |
| writeShort(mappings.size()); |
| mappings.forEach((prefix, uri) -> { |
| writeString(prefix); |
| writeString(uri); |
| }); |
| writeString(idc.getSourceName()); |
| } |
| |
| 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 (SchemaParticle schemaParticle : spa) { |
| writeParticleData(schemaParticle); |
| } |
| } |
| |
| SchemaParticle readParticleData() { |
| int particleType = readShort(); |
| SchemaParticleImpl result; |
| if (particleType != SchemaParticle.ELEMENT) { |
| result = new SchemaParticleImpl(); |
| } else { |
| result = new SchemaLocalElementImpl(); |
| } |
| loadParticle(result, particleType); |
| return result; |
| } |
| |
| void loadParticle(SchemaParticleImpl result, int particleType) { |
| int 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); |
| lresult.setAnnotation(readAnnotation(null)); |
| |
| 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 ", typeSystem.getName(), _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()); |
| writeAnnotation(lpart.getAnnotation()); |
| if (lpart instanceof SchemaGlobalElement) { |
| SchemaGlobalElement gpart = (SchemaGlobalElement) lpart; |
| |
| writeHandle(gpart.substitutionGroup()); |
| |
| QName[] substGroupMembers = gpart.substitutionGroupMembers(); |
| writeShort(substGroupMembers.length); |
| for (QName substGroupMember : substGroupMembers) { |
| writeQName(substGroupMember); |
| } |
| } |
| |
| SchemaIdentityConstraint[] idcs = lpart.getIdentityConstraints(); |
| |
| writeShort(idcs.length); |
| for (SchemaIdentityConstraint idc : idcs) { |
| writeHandle(idc); |
| } |
| |
| break; |
| |
| case SchemaParticle.ALL: |
| case SchemaParticle.SEQUENCE: |
| case SchemaParticle.CHOICE: |
| writeParticleArray(part.getParticleChildren()); |
| break; |
| |
| default: |
| throw new SchemaTypeLoaderException("Unrecognized particle type ", typeSystem.getName(), _handle, SchemaTypeLoaderException.BAD_PARTICLE_TYPE); |
| } |
| } |
| |
| SchemaProperty readPropertyData() { |
| SchemaPropertyImpl prop = new SchemaPropertyImpl(); |
| prop.setName(readQName()); |
| prop.setTypeRef(readTypeRef()); |
| int 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); |
| if (atMost(2, 19, 0)) { |
| prop.setJavaSetterDelimiter(readQNameSet()); |
| } |
| if (atLeast(2, 16, 0)) { |
| prop.setDefaultValue(readXmlValueObject()); |
| } |
| |
| if (!prop.isAttribute() && atLeast(2, 17, 0)) { |
| int size = readShort(); |
| Set<QName> 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()); |
| writeXmlValueObject(prop.getDefaultValue()); |
| |
| if (!prop.isAttribute()) { |
| QName[] names = prop.acceptedNames(); |
| writeShort(names.length); |
| for (QName name : names) { |
| writeQName(name); |
| } |
| } |
| } |
| |
| void writeModelGroupData(SchemaModelGroup grp) { |
| SchemaModelGroupImpl impl = (SchemaModelGroupImpl) grp; |
| writeQName(impl.getName()); |
| writeString(impl.getTargetNamespace()); |
| writeShort(impl.getChameleonNamespace() != null ? 1 : 0); |
| writeString(impl.getElemFormDefault()); // new for version 2.22 |
| writeString(impl.getAttFormDefault()); // new for version 2.22 |
| writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15 |
| writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter())); |
| writeAnnotation(impl.getAnnotation()); |
| writeString(impl.getSourceName()); |
| } |
| |
| void writeAttributeGroupData(SchemaAttributeGroup grp) { |
| SchemaAttributeGroupImpl impl = (SchemaAttributeGroupImpl) grp; |
| writeQName(impl.getName()); |
| writeString(impl.getTargetNamespace()); |
| writeShort(impl.getChameleonNamespace() != null ? 1 : 0); |
| writeString(impl.getFormDefault()); // new for version 2.22 |
| writeShort(impl.isRedefinition() ? 1 : 0); // new for version 2.15 |
| writeString(impl.getParseObject().xmlText(new XmlOptions().setSaveOuter())); |
| writeAnnotation(impl.getAnnotation()); |
| writeString(impl.getSourceName()); |
| } |
| |
| 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 0xFFFF: { |
| int size = readShort(); |
| List<XmlValueRef> values = new ArrayList<>(); |
| // BUGBUG: this was: writeShort(values.size()); |
| writeShort(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, 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<? extends XmlAnySimpleType> values = ((XmlObjectBase) value).xgetListValue(); |
| writeShort(values.size()); |
| values.forEach(this::writeXmlValueObject); |
| } 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(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| |
| void writeDouble(double d) { |
| if (_output != null) { |
| try { |
| _output.writeDouble(d); |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| } |
| |
| QNameSet readQNameSet() { |
| int flag = readShort(); |
| |
| Set<String> uriSet = new HashSet<>(); |
| int uriCount = readShort(); |
| for (int i = 0; i < uriCount; i++) { |
| uriSet.add(readString()); |
| } |
| |
| Set<QName> qnameSet1 = new HashSet<>(); |
| int qncount1 = readShort(); |
| for (int i = 0; i < qncount1; i++) { |
| qnameSet1.add(readQName()); |
| } |
| |
| Set<QName> qnameSet2 = new HashSet<>(); |
| int 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<String> uriSet = invert ? set.excludedURIs() : set.includedURIs(); |
| assert (uriSet != null); |
| writeShort(uriSet.size()); |
| uriSet.forEach(this::writeString); |
| |
| Set<QName> qnameSet1 = invert ? set.excludedQNamesInIncludedURIs() : set.includedQNamesInExcludedURIs(); |
| writeShort(qnameSet1.size()); |
| qnameSet1.forEach(this::writeQName); |
| |
| Set<QName> qnameSet2 = invert ? set.includedQNamesInExcludedURIs() : set.excludedQNamesInIncludedURIs(); |
| writeShort(qnameSet2.size()); |
| qnameSet2.forEach(this::writeQName); |
| } |
| |
| byte[] readByteArray() { |
| try { |
| int len = _input.readShort(); |
| byte[] result = new byte[len]; |
| _input.readFully(result); |
| return result; |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| |
| void writeByteArray(byte[] ba) { |
| try { |
| writeShort(ba.length); |
| if (_output != null) { |
| _output.write(ba); |
| } |
| } catch (IOException e) { |
| throw new SchemaTypeLoaderException(e.getMessage(), typeSystem.getName(), _handle, SchemaTypeLoaderException.IO_EXCEPTION, e); |
| } |
| } |
| |
| 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()); |
| } |
| } |
| |
| } |
| |